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 |