Index: storage/browser/blob/blob_async_transport_request_builder.cc |
diff --git a/storage/browser/blob/blob_async_transport_request_builder.cc b/storage/browser/blob/blob_async_transport_request_builder.cc |
deleted file mode 100644 |
index 6a68050b0d59b7780f6878d818ee451c3b56a197..0000000000000000000000000000000000000000 |
--- a/storage/browser/blob/blob_async_transport_request_builder.cc |
+++ /dev/null |
@@ -1,299 +0,0 @@ |
-// Copyright 2015 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include <stddef.h> |
-#include <stdint.h> |
- |
-#include <algorithm> |
- |
-#include "base/numerics/safe_math.h" |
-#include "storage/browser/blob/blob_async_transport_request_builder.h" |
-#include "storage/common/blob_storage/blob_storage_constants.h" |
- |
-namespace storage { |
-namespace { |
-bool IsBytes(DataElement::Type type) { |
- return type == DataElement::TYPE_BYTES || |
- type == DataElement::TYPE_BYTES_DESCRIPTION; |
-} |
- |
-// This is the general template that each strategy below implements. See the |
-// ForEachWithSegment method for a description of how these are called. |
-// class BlobSegmentVisitor { |
-// public: |
-// typedef ___ SizeType; |
-// void VisitBytesSegment(size_t element_index, uint64_t element_offset, |
-// size_t segment_index, uint64_t segment_offset, |
-// uint64_t size); |
-// void VisitNonBytesSegment(const DataElement& element, size_t element_idx); |
-// void Done(); |
-// }; |
- |
-// This class handles the logic of how transported memory is going to be |
-// represented as storage in the browser. The main idea is that all the memory |
-// is now packed into file chunks, and the browser items will just reference |
-// the file with offsets and sizes. |
-class FileStorageStrategy { |
- public: |
- FileStorageStrategy( |
- std::vector<BlobAsyncTransportRequestBuilder::RendererMemoryItemRequest>* |
- requests, |
- BlobDataBuilder* builder) |
- : requests(requests), builder(builder), current_item_index(0) {} |
- |
- ~FileStorageStrategy() {} |
- |
- void VisitBytesSegment(size_t element_index, |
- uint64_t element_offset, |
- size_t segment_index, |
- uint64_t segment_offset, |
- uint64_t size) { |
- BlobAsyncTransportRequestBuilder::RendererMemoryItemRequest request; |
- request.browser_item_index = current_item_index; |
- request.browser_item_offset = 0; |
- request.message.request_number = requests->size(); |
- request.message.transport_strategy = IPCBlobItemRequestStrategy::FILE; |
- request.message.renderer_item_index = element_index; |
- request.message.renderer_item_offset = element_offset; |
- request.message.size = size; |
- request.message.handle_index = segment_index; |
- request.message.handle_offset = segment_offset; |
- |
- requests->push_back(request); |
- builder->AppendFutureFile(segment_offset, size, segment_index); |
- current_item_index++; |
- } |
- |
- void VisitNonBytesSegment(const DataElement& element, size_t element_index) { |
- builder->AppendIPCDataElement(element); |
- current_item_index++; |
- } |
- |
- void Done() {} |
- |
- std::vector<BlobAsyncTransportRequestBuilder::RendererMemoryItemRequest>* |
- requests; |
- BlobDataBuilder* builder; |
- |
- size_t current_item_index; |
-}; |
- |
-// This class handles the logic of storing memory that is transported as |
-// consolidated shared memory. |
-class SharedMemoryStorageStrategy { |
- public: |
- SharedMemoryStorageStrategy( |
- size_t max_segment_size, |
- std::vector<BlobAsyncTransportRequestBuilder::RendererMemoryItemRequest>* |
- requests, |
- BlobDataBuilder* builder) |
- : requests(requests), |
- max_segment_size(max_segment_size), |
- builder(builder), |
- current_item_size(0), |
- current_item_index(0) {} |
- ~SharedMemoryStorageStrategy() {} |
- |
- void VisitBytesSegment(size_t element_index, |
- uint64_t element_offset, |
- size_t segment_index, |
- uint64_t segment_offset, |
- uint64_t size) { |
- if (current_item_size + size > max_segment_size) { |
- builder->AppendFutureData(current_item_size); |
- current_item_index++; |
- current_item_size = 0; |
- } |
- BlobAsyncTransportRequestBuilder::RendererMemoryItemRequest request; |
- request.browser_item_index = current_item_index; |
- request.browser_item_offset = current_item_size; |
- request.message.request_number = requests->size(); |
- request.message.transport_strategy = |
- IPCBlobItemRequestStrategy::SHARED_MEMORY; |
- request.message.renderer_item_index = element_index; |
- request.message.renderer_item_offset = element_offset; |
- request.message.size = size; |
- request.message.handle_index = segment_index; |
- request.message.handle_offset = segment_offset; |
- |
- requests->push_back(request); |
- current_item_size += size; |
- } |
- |
- void VisitNonBytesSegment(const DataElement& element, size_t element_index) { |
- if (current_item_size != 0) { |
- builder->AppendFutureData(current_item_size); |
- current_item_index++; |
- } |
- builder->AppendIPCDataElement(element); |
- current_item_index++; |
- current_item_size = 0; |
- } |
- |
- void Done() { |
- if (current_item_size != 0) { |
- builder->AppendFutureData(current_item_size); |
- } |
- } |
- |
- std::vector<BlobAsyncTransportRequestBuilder::RendererMemoryItemRequest>* |
- requests; |
- |
- size_t max_segment_size; |
- BlobDataBuilder* builder; |
- size_t current_item_size; |
- uint64_t current_item_index; |
-}; |
- |
-// This iterates of the data elements and segments the 'bytes' data into |
-// the smallest number of segments given the max_segment_size. |
-// The callback describes either: |
-// * A non-memory item |
-// * A partition of a bytes element which will be populated into a given |
-// segment and segment offset. |
-// More specifically, we split each |element| into one or more |segments| of a |
-// max_size, invokes the strategy to determine the request to make for each |
-// |segment| produced. A |segment| can also span multiple |elements|. |
-// Assumptions: All memory items are consolidated. As in, there are no two |
-// 'bytes' items next to eachother. |
-template <typename Visitor> |
-void ForEachWithSegment(const std::vector<DataElement>& elements, |
- uint64_t max_segment_size, |
- Visitor* visitor) { |
- DCHECK_GT(max_segment_size, 0ull); |
- size_t segment_index = 0; |
- uint64_t segment_offset = 0; |
- size_t elements_length = elements.size(); |
- for (size_t element_index = 0; element_index < elements_length; |
- ++element_index) { |
- const auto& element = elements.at(element_index); |
- DataElement::Type type = element.type(); |
- if (!IsBytes(type)) { |
- visitor->VisitNonBytesSegment(element, element_index); |
- continue; |
- } |
- uint64_t element_memory_left = element.length(); |
- uint64_t element_offset = 0; |
- while (element_memory_left > 0) { |
- if (segment_offset == max_segment_size) { |
- ++segment_index; |
- segment_offset = 0; |
- } |
- uint64_t memory_writing = |
- std::min(max_segment_size - segment_offset, element_memory_left); |
- visitor->VisitBytesSegment(element_index, element_offset, segment_index, |
- segment_offset, memory_writing); |
- element_memory_left -= memory_writing; |
- segment_offset += memory_writing; |
- element_offset += memory_writing; |
- } |
- } |
- visitor->Done(); |
-} |
-} // namespace |
- |
-BlobAsyncTransportRequestBuilder::RendererMemoryItemRequest:: |
- RendererMemoryItemRequest() |
- : browser_item_index(0), browser_item_offset(0) {} |
- |
-BlobAsyncTransportRequestBuilder::BlobAsyncTransportRequestBuilder() |
- : total_bytes_size_(0) {} |
- |
-BlobAsyncTransportRequestBuilder::~BlobAsyncTransportRequestBuilder() {} |
- |
-// Initializes the transport strategy for file requests. |
-void BlobAsyncTransportRequestBuilder::InitializeForFileRequests( |
- size_t max_file_size, |
- uint64_t blob_total_size, |
- const std::vector<DataElement>& elements, |
- BlobDataBuilder* builder) { |
- DCHECK(requests_.empty()); |
- total_bytes_size_ = blob_total_size; |
- ComputeHandleSizes(total_bytes_size_, max_file_size, &file_sizes_); |
- FileStorageStrategy strategy(&requests_, builder); |
- ForEachWithSegment(elements, static_cast<uint64_t>(max_file_size), &strategy); |
-} |
- |
-void BlobAsyncTransportRequestBuilder::InitializeForSharedMemoryRequests( |
- size_t max_shared_memory_size, |
- uint64_t blob_total_size, |
- const std::vector<DataElement>& elements, |
- BlobDataBuilder* builder) { |
- DCHECK(requests_.empty()); |
- DCHECK(blob_total_size <= std::numeric_limits<size_t>::max()); |
- total_bytes_size_ = blob_total_size; |
- ComputeHandleSizes(total_bytes_size_, max_shared_memory_size, |
- &shared_memory_sizes_); |
- SharedMemoryStorageStrategy strategy(max_shared_memory_size, &requests_, |
- builder); |
- ForEachWithSegment(elements, static_cast<uint64_t>(max_shared_memory_size), |
- &strategy); |
-} |
- |
-void BlobAsyncTransportRequestBuilder::InitializeForIPCRequests( |
- size_t max_ipc_memory_size, |
- uint64_t blob_total_size, |
- const std::vector<DataElement>& elements, |
- BlobDataBuilder* builder) { |
- DCHECK(requests_.empty()); |
- // We don't segment anything, and just request the memory items directly |
- // in IPC. |
- size_t items_length = elements.size(); |
- total_bytes_size_ = blob_total_size; |
- for (size_t i = 0; i < items_length; i++) { |
- const auto& info = elements.at(i); |
- if (!IsBytes(info.type())) { |
- builder->AppendIPCDataElement(info); |
- continue; |
- } |
- BlobAsyncTransportRequestBuilder::RendererMemoryItemRequest request; |
- request.browser_item_index = i; |
- request.browser_item_offset = 0; |
- request.message.request_number = requests_.size(); |
- request.message.transport_strategy = IPCBlobItemRequestStrategy::IPC; |
- request.message.renderer_item_index = i; |
- request.message.renderer_item_offset = 0; |
- request.message.size = info.length(); |
- requests_.push_back(request); |
- builder->AppendFutureData(info.length()); |
- } |
-} |
- |
-/* static */ |
-bool BlobAsyncTransportRequestBuilder::ShouldBeShortcut( |
- const std::vector<DataElement>& elements, |
- size_t memory_available) { |
- base::CheckedNumeric<size_t> shortcut_bytes = 0; |
- for (const auto& element : elements) { |
- DataElement::Type type = element.type(); |
- if (type == DataElement::TYPE_BYTES_DESCRIPTION) { |
- return false; |
- } |
- if (type == DataElement::TYPE_BYTES) { |
- shortcut_bytes += element.length(); |
- if (!shortcut_bytes.IsValid()) { |
- return false; |
- } |
- } |
- } |
- return shortcut_bytes.ValueOrDie() <= memory_available; |
-} |
- |
-/* static */ |
-void BlobAsyncTransportRequestBuilder::ComputeHandleSizes( |
- uint64_t total_memory_size, |
- size_t max_segment_size, |
- std::vector<size_t>* segment_sizes) { |
- size_t total_max_segments = |
- static_cast<size_t>(total_memory_size / max_segment_size); |
- bool has_extra_segment = (total_memory_size % max_segment_size) > 0; |
- segment_sizes->reserve(total_max_segments + (has_extra_segment ? 1 : 0)); |
- segment_sizes->insert(segment_sizes->begin(), total_max_segments, |
- max_segment_size); |
- if (has_extra_segment) { |
- segment_sizes->push_back(total_memory_size % max_segment_size); |
- } |
-} |
- |
-} // namespace storage |