| Index: storage/browser/blob/blob_async_transport_strategy.h | 
| diff --git a/storage/browser/blob/blob_async_transport_strategy.h b/storage/browser/blob/blob_async_transport_strategy.h | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..d00c89f63ea878a2dde6027c5751344c03e548bd | 
| --- /dev/null | 
| +++ b/storage/browser/blob/blob_async_transport_strategy.h | 
| @@ -0,0 +1,167 @@ | 
| +// 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. | 
| + | 
| +#ifndef STORAGE_BROWSER_BLOB_BLOB_ASYNC_TRANSPORT_STRATEGY_H_ | 
| +#define STORAGE_BROWSER_BLOB_BLOB_ASYNC_TRANSPORT_STRATEGY_H_ | 
| + | 
| +#include <map> | 
| +#include <vector> | 
| + | 
| +#include "base/macros.h" | 
| +#include "base/memory/scoped_ptr.h" | 
| +#include "storage/browser/blob/blob_data_builder.h" | 
| +#include "storage/browser/storage_browser_export.h" | 
| +#include "storage/common/blob_storage/blob_item_bytes_request.h" | 
| +#include "storage/common/data_element.h" | 
| + | 
| +namespace storage { | 
| +class FileStorageStrategy; | 
| +class SharedMemoryStorageStrategy; | 
| + | 
| +// This class computes and stores the strategy for asynchronously transporting | 
| +// memory from the renderer to the browser. | 
| +// | 
| +// tl;dr: | 
| +// We take memory constraints of our system and the description of a blob, and | 
| +// generate data requests for that blob's memory and a seed a BlobDataBuilder | 
| +// for storing that data. | 
| +// | 
| +// This class does not compute requests by using the 'shortcut' method, where | 
| +// the data is already present in the blob description, and will always give | 
| +// the caller the full strategy for requesting all data from the renderer. The | 
| +// returned builder will always have TYPE_BYTES_DESCRIPTION items for the future | 
| +// memory locations. | 
| +// This involves two transformations: | 
| +// 1. Transforming the data storage to be efficient in-transport.  This can | 
| +//    mean that data is consolidated from cross-blob or cross-file boundaries | 
| +//    in the blob in a common block of shared memory or a file. | 
| +// 2. Transforming the transport data into the browser storage representation. | 
| +//    This can simply mirror the renderer representation, or it can be instead | 
| +//    pointing to transport representation with offsets and sizes. | 
| +// | 
| +// The following information is generated: | 
| +// 1. The total bytes size of memory items. | 
| +// 2. The requests for memory, segmented as described above, along with their | 
| +//    destination browser indexes and offsets | 
| +// 3. The sizes of the shared memory and file handles being used (by handle | 
| +//    index) in the async operation. | 
| +// 4. A BlobDataBuilder which can be used to construct the Blob in the | 
| +//    BlobStorageContext object, after the TYPE_BYTES_DESCRIPTION entries are | 
| +//    turned into TYPE_BYTES entries. | 
| +// The initial implementation of this is simple, but the protocol allows any | 
| +// sort of flexibility, as everything has an offset and size specified. | 
| +class STORAGE_EXPORT BlobAsyncTransportStrategy { | 
| + public: | 
| +  enum Error { | 
| +    ERROR_NONE = 0, | 
| +    ERROR_TOO_LARGE,  // This item can't fit in disk or memory | 
| +    ERROR_INVALID_PARAMS | 
| +  }; | 
| + | 
| +  struct RendererMemoryItemRequest { | 
| +    RendererMemoryItemRequest(); | 
| +    // This is the index of the item in the builder on the browser side. | 
| +    size_t browser_item_index; | 
| +    // Note: For files this offset should always be 0, as the file offset in | 
| +    //       segmentation is handled by the handle_offset in the message.  This | 
| +    //       offset is used for populating a chunk when the data comes back to | 
| +    //       the browser. | 
| +    size_t browser_item_offset; | 
| +    BlobItemBytesRequest message; | 
| +    bool received; | 
| +  }; | 
| + | 
| +  BlobAsyncTransportStrategy(); | 
| +  virtual ~BlobAsyncTransportStrategy(); | 
| + | 
| +  // This call does the computation to create the requests and builder for the | 
| +  // blob given the memory constraints and blob description. | 
| +  // 'memory_available' is the total amount of memory we can offer for storing | 
| +  // blobs. | 
| +  void Initialize(size_t max_ipc_memory_size, | 
| +                  size_t max_shared_memory_size, | 
| +                  uint64_t max_file_size, | 
| +                  uint64_t disk_space_left, | 
| +                  size_t memory_available, | 
| +                  const std::string& uuid, | 
| +                  const std::vector<DataElement>& blob_item_infos); | 
| + | 
| +  // In the current algorithm, the file sizes will always be sorted from largest | 
| +  // to smallest. | 
| +  std::vector<uint64_t>& file_handle_sizes() { return file_handle_sizes_; } | 
| + | 
| +  // In the current algorithm, the shared memory sizes will always be sorted | 
| +  // from largest to smallest. | 
| +  std::vector<size_t>& shared_memory_handle_sizes() { | 
| +    return shared_memory_handle_sizes_; | 
| +  } | 
| + | 
| +  const std::vector<RendererMemoryItemRequest>& requests() const { | 
| +    return requests_; | 
| +  } | 
| + | 
| +  BlobDataBuilder* blob_builder() { return builder_.get(); } | 
| + | 
| +  uint64_t total_bytes_size() const { return total_bytes_size_; } | 
| + | 
| +  Error error() const { return error_; } | 
| + | 
| +  static bool ShouldBeShortcut(const std::vector<DataElement>& items, | 
| +                               size_t memory_available); | 
| + | 
| + protected: | 
| +  friend class FileStorageStrategy; | 
| +  friend class SharedMemoryStorageStrategy; | 
| + | 
| +  template <typename SizeType> | 
| +  class BlobSegmentVisitor { | 
| +   public: | 
| +    virtual ~BlobSegmentVisitor(){}; | 
| +    virtual void VisitBytesSegment(size_t element_index, | 
| +                                   SizeType element_offset, | 
| +                                   size_t segment_index, | 
| +                                   SizeType segment_offset, | 
| +                                   SizeType size) = 0; | 
| +    virtual void VisitNonBytesSegment(const DataElement& element, | 
| +                                      size_t element_index) = 0; | 
| +    virtual void Done() = 0; | 
| +  }; | 
| + | 
| +  // 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. | 
| +  // Assumptions: All memory items are consolidated.  As in, there are no two | 
| +  //              'bytes' items next to eachother. | 
| +  template <typename SizeType> | 
| +  static void ForEachWithSegment(const std::vector<DataElement>& items, | 
| +                                 SizeType max_segment_size, | 
| +                                 BlobSegmentVisitor<SizeType>* visitor); | 
| + | 
| + private: | 
| +  // This simply fills the segment_sizes vector with the sizes of segments that | 
| +  // would be used to partition a block of total_memory_size. | 
| +  template <typename SizeType> | 
| +  static void ComputeHandleSizes(SizeType total_memory_size, | 
| +                                 SizeType max_segment_size, | 
| +                                 std::vector<SizeType>* segment_sizes); | 
| + | 
| +  Error error_; | 
| + | 
| +  std::vector<uint64_t> file_handle_sizes_; | 
| +  // can be size_t, but same as file handles so we can use the same methods. | 
| +  std::vector<size_t> shared_memory_handle_sizes_; | 
| + | 
| +  uint64_t total_bytes_size_; | 
| +  std::vector<RendererMemoryItemRequest> requests_; | 
| +  scoped_ptr<BlobDataBuilder> builder_; | 
| + | 
| +  DISALLOW_COPY_AND_ASSIGN(BlobAsyncTransportStrategy); | 
| +}; | 
| + | 
| +}  // namespace storage | 
| + | 
| +#endif  // STORAGE_BROWSER_BLOB_BLOB_ASYNC_TRANSPORT_STRATEGY_H_ | 
|  |