Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // TODO: Insert description here. (generated by dmurph) | |
| 2 | |
| 3 #include "storage/browser/blob/blob_flattener.h" | |
| 4 | |
| 5 #include <limits> | |
| 6 #include <set> | |
| 7 #include <utility> | |
| 8 | |
| 9 #include "storage/browser/blob/blob_async_transport_request_builder.h" | |
| 10 #include "storage/browser/blob/blob_data_builder.h" | |
| 11 #include "storage/browser/blob/blob_storage_context.h" | |
| 12 #include "storage/browser/blob/blob_storage_registry.h" | |
| 13 #include "storage/browser/blob/shareable_blob_data_item.h" | |
| 14 | |
| 15 namespace storage { | |
| 16 namespace { | |
| 17 using ItemCopyEntry = BlobStorageRegistry::ItemCopyEntry; | |
| 18 using BlobEntry = BlobStorageRegistry::Entry; | |
| 19 | |
| 20 bool IsBytes(DataElement::Type type) { | |
| 21 return type == DataElement::TYPE_BYTES || | |
| 22 type == DataElement::TYPE_BYTES_DESCRIPTION; | |
| 23 } | |
| 24 | |
| 25 } // namespace | |
| 26 | |
| 27 // static | |
| 28 BlobFlattener::BlobFlattener(const BlobDataBuilder& transportation_result, | |
| 29 InternalBlobData* output_blob, | |
| 30 BlobStorageRegistry* registry) { | |
| 31 const std::vector<scoped_refptr<BlobDataItem>>& transport_items = | |
| 32 transportation_result.items_; | |
| 33 const std::string& uuid = transportation_result.uuid_; | |
| 34 | |
| 35 std::set<std::string> dependent_blob_uuids; | |
| 36 for (size_t transport_item_index = 0; | |
| 37 transport_item_index < transport_items.size(); transport_item_index++) { | |
| 38 scoped_refptr<BlobDataItem> transport_item = | |
| 39 transport_items[transport_item_index]; | |
| 40 | |
| 41 DataElement::Type type = transport_item->type(); | |
| 42 contains_pending_content |= type == DataElement::TYPE_BYTES_DESCRIPTION; | |
| 43 | |
| 44 if (IsBytes(type)) { | |
| 45 memory_needed += transport_item->length(); | |
| 46 total_size += transport_item->length(); | |
| 47 output_blob->AppendSharedBlobItem( | |
| 48 uuid, new ShareableBlobDataItem(std::move(transport_item))); | |
| 49 } else if (type == DataElement::TYPE_BLOB) { | |
| 50 BlobEntry* ref_entry = registry->GetEntry(transport_item->blob_uuid()); | |
| 51 | |
| 52 if (!ref_entry || BlobStatusIsError(ref_entry->status) || | |
| 53 transport_item->blob_uuid() == uuid) { | |
| 54 contains_broken_references = true; | |
| 55 return; | |
| 56 } | |
| 57 | |
| 58 if (dependent_blob_uuids.find(transport_item->blob_uuid()) == | |
| 59 dependent_blob_uuids.end()) { | |
| 60 dependent_blobs.push_back( | |
| 61 std::make_pair(transport_item->blob_uuid(), ref_entry)); | |
| 62 dependent_blob_uuids.insert(transport_item->blob_uuid()); | |
| 63 } | |
| 64 | |
| 65 uint64_t length = | |
| 66 transport_item->length() == std::numeric_limits<uint64_t>::max() | |
|
Marijn Kruisselbrink
2016/07/12 21:33:06
if ::max() is a magic number for the length of a t
dmurph
2016/07/14 01:04:31
Yes, that sounds good.
| |
| 67 ? ref_entry->data.total_size() | |
| 68 : transport_item->length(); | |
| 69 | |
| 70 total_size += length; | |
| 71 | |
| 72 // If we're referencing the whole blob, then we don't need to slice. | |
| 73 if (transport_item->offset() == 0 && | |
| 74 length == ref_entry->data.total_size()) { | |
| 75 for (const auto& shareable_item : ref_entry->data.items()) { | |
| 76 output_blob->AppendSharedBlobItem(uuid, shareable_item); | |
| 77 } | |
| 78 continue; | |
| 79 } | |
| 80 | |
| 81 BlobSlice slice(ref_entry->data, transport_item->offset(), | |
| 82 transport_item->length()); | |
| 83 | |
| 84 if (slice.has_sliced_first_memory_item) { | |
| 85 copies.push_back(ItemCopyEntry(slice.first_source_item, | |
| 86 slice.first_item_slice_offset, | |
| 87 slice.dest_items.front())); | |
| 88 } | |
| 89 | |
| 90 memory_needed += slice.copying_memory_size; | |
| 91 for (auto& shareable_item : slice.dest_items) { | |
| 92 output_blob->AppendSharedBlobItem(uuid, std::move(shareable_item)); | |
| 93 } | |
| 94 | |
| 95 if (slice.has_sliced_last_memory_item) { | |
| 96 copies.push_back( | |
| 97 ItemCopyEntry(slice.last_source_item, 0, slice.dest_items.back())); | |
|
Marijn Kruisselbrink
2016/07/12 21:33:06
Does this work? Above you've moved all the items i
dmurph
2016/07/14 01:04:31
Yep, nice bug catch.
| |
| 98 } | |
| 99 } else { | |
| 100 if (type == DataElement::TYPE_FILE) { | |
| 101 contains_pending_content = | |
| 102 transport_item->path().value() == | |
| 103 BlobDataBuilder::kAppendFutureFileTemporaryFileName; | |
| 104 } | |
| 105 total_size += transport_item->length(); | |
| 106 output_blob->AppendSharedBlobItem( | |
| 107 uuid, new ShareableBlobDataItem(std::move(transport_item))); | |
| 108 } | |
| 109 } | |
| 110 } | |
| 111 | |
| 112 BlobFlattener::~BlobFlattener() {} | |
| 113 | |
| 114 } // namespace storage | |
| OLD | NEW |