OLD | NEW |
---|---|
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 "storage/browser/blob/blob_storage_context.h" | 5 #include "storage/browser/blob/blob_storage_context.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <limits> | 8 #include <limits> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
88 public_blob_urls_.find(BlobUrlHasRef(url) ? ClearBlobUrlRef(url) : url); | 88 public_blob_urls_.find(BlobUrlHasRef(url) ? ClearBlobUrlRef(url) : url); |
89 if (found == public_blob_urls_.end()) | 89 if (found == public_blob_urls_.end()) |
90 return scoped_ptr<BlobDataHandle>(); | 90 return scoped_ptr<BlobDataHandle>(); |
91 return GetBlobDataFromUUID(found->second); | 91 return GetBlobDataFromUUID(found->second); |
92 } | 92 } |
93 | 93 |
94 scoped_ptr<BlobDataHandle> BlobStorageContext::AddFinishedBlob( | 94 scoped_ptr<BlobDataHandle> BlobStorageContext::AddFinishedBlob( |
95 BlobDataBuilder* external_builder) { | 95 BlobDataBuilder* external_builder) { |
96 TRACE_EVENT0("Blob", "Context::AddFinishedBlob"); | 96 TRACE_EVENT0("Blob", "Context::AddFinishedBlob"); |
97 StartBuildingBlob(external_builder->uuid_); | 97 StartBuildingBlob(external_builder->uuid_); |
98 DCHECK_EQ(1U, blob_map_.count(external_builder->uuid_)); | |
jkarlin
2015/05/29 14:59:41
Why this change?
gavinp
2015/05/29 18:06:07
I don't like doing DCHECK with == or != in them; i
| |
98 BlobMap::iterator found = blob_map_.find(external_builder->uuid_); | 99 BlobMap::iterator found = blob_map_.find(external_builder->uuid_); |
99 DCHECK(found != blob_map_.end()); | |
100 BlobMapEntry* entry = found->second; | 100 BlobMapEntry* entry = found->second; |
101 InternalBlobData::Builder* target_blob_builder = entry->data_builder.get(); | 101 InternalBlobData::Builder* target_blob_builder = entry->data_builder.get(); |
102 DCHECK(target_blob_builder); | 102 DCHECK(target_blob_builder); |
103 | 103 |
104 target_blob_builder->set_content_disposition( | 104 target_blob_builder->set_content_disposition( |
105 external_builder->content_disposition_); | 105 external_builder->content_disposition_); |
106 for (const auto& blob_item : external_builder->items_) { | 106 for (const auto& blob_item : external_builder->items_) { |
107 if (!AppendAllocatedBlobItem(external_builder->uuid_, blob_item, | 107 if (!AppendAllocatedBlobItem(external_builder->uuid_, blob_item, |
108 target_blob_builder)) { | 108 target_blob_builder)) { |
109 BlobEntryExceededMemory(entry); | 109 BlobEntryExceededMemory(entry); |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
276 ipc_data.offset(), length, | 276 ipc_data.offset(), length, |
277 ipc_data.expected_modification_time()); | 277 ipc_data.expected_modification_time()); |
278 blob_item = new BlobDataItem(element.Pass()); | 278 blob_item = new BlobDataItem(element.Pass()); |
279 break; | 279 break; |
280 case DataElement::TYPE_BLOB: | 280 case DataElement::TYPE_BLOB: |
281 // This is a temporary item that will be deconstructed later. | 281 // This is a temporary item that will be deconstructed later. |
282 element->SetToBlobRange(ipc_data.blob_uuid(), ipc_data.offset(), | 282 element->SetToBlobRange(ipc_data.blob_uuid(), ipc_data.offset(), |
283 ipc_data.length()); | 283 ipc_data.length()); |
284 blob_item = new BlobDataItem(element.Pass()); | 284 blob_item = new BlobDataItem(element.Pass()); |
285 break; | 285 break; |
286 case DataElement::TYPE_DISK_CACHE_ENTRY: // This type can't be sent by IPC. | |
jkarlin
2015/05/29 14:59:42
Add NOTREACHED().
gavinp
2015/05/29 18:06:07
Done.
| |
286 default: | 287 default: |
287 NOTREACHED(); | 288 NOTREACHED(); |
288 break; | 289 break; |
289 } | 290 } |
290 | 291 |
291 return blob_item; | 292 return blob_item; |
292 } | 293 } |
293 | 294 |
294 bool BlobStorageContext::AppendAllocatedBlobItem( | 295 bool BlobStorageContext::AppendAllocatedBlobItem( |
295 const std::string& target_blob_uuid, | 296 const std::string& target_blob_uuid, |
296 scoped_refptr<BlobDataItem> blob_item, | 297 scoped_refptr<BlobDataItem> blob_item, |
297 InternalBlobData::Builder* target_blob_builder) { | 298 InternalBlobData::Builder* target_blob_builder) { |
298 bool exceeded_memory = false; | 299 bool exceeded_memory = false; |
299 | 300 |
300 // The blob data is stored in the canonical way which only contains a | 301 // The blob data is stored in the canonical way which only contains a |
301 // list of Data, File, and FileSystem items. Aggregated TYPE_BLOB items | 302 // list of Data, File, and FileSystem items. Aggregated TYPE_BLOB items |
302 // are expanded into the primitive constituent types and reused if possible. | 303 // are expanded into the primitive constituent types and reused if possible. |
303 // 1) The Data item is denoted by the raw data and length. | 304 // 1) The Data item is denoted by the raw data and length. |
304 // 2) The File item is denoted by the file path, the range and the expected | 305 // 2) The File item is denoted by the file path, the range and the expected |
305 // modification time. | 306 // modification time. |
306 // 3) The FileSystem File item is denoted by the FileSystem URL, the range | 307 // 3) The FileSystem File item is denoted by the FileSystem URL, the range |
307 // and the expected modification time. | 308 // and the expected modification time. |
jkarlin
2015/05/29 14:59:42
Add your new type's description to this comment as
gavinp
2015/05/29 18:06:07
Done.
This is why I hate comments like this.
| |
308 // 4) The Blob item is denoted by the source blob and an offset and size. | 309 // 4) The Blob item is denoted by the source blob and an offset and size. |
309 // Internal items that are fully used by the new blob (not cut by the | 310 // Internal items that are fully used by the new blob (not cut by the |
310 // offset or size) are shared between the blobs. Otherwise, the relevant | 311 // offset or size) are shared between the blobs. Otherwise, the relevant |
311 // portion of the item is copied. | 312 // portion of the item is copied. |
312 | 313 |
313 const DataElement& data_element = blob_item->data_element(); | 314 uint64 length = blob_item->GetLength(); |
314 uint64 length = data_element.length(); | 315 uint64 offset = blob_item->GetOffset(); |
315 uint64 offset = data_element.offset(); | |
316 UMA_HISTOGRAM_COUNTS("Storage.Blob.StorageSizeBeforeAppend", | 316 UMA_HISTOGRAM_COUNTS("Storage.Blob.StorageSizeBeforeAppend", |
317 memory_usage_ / 1024); | 317 memory_usage_ / 1024); |
318 switch (data_element.type()) { | 318 switch (blob_item->data_element().type()) { |
319 case DataElement::TYPE_BYTES: | 319 case DataElement::TYPE_BYTES: |
320 UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.Bytes", length / 1024); | 320 UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.Bytes", length / 1024); |
321 DCHECK(!offset); | 321 DCHECK(!offset); |
322 if (memory_usage_ + length > kMaxMemoryUsage) { | 322 if (memory_usage_ + length > kMaxMemoryUsage) { |
323 exceeded_memory = true; | 323 exceeded_memory = true; |
324 break; | 324 break; |
325 } | 325 } |
326 memory_usage_ += length; | 326 memory_usage_ += length; |
327 target_blob_builder->AppendSharedBlobItem( | 327 target_blob_builder->AppendSharedBlobItem( |
328 new ShareableBlobDataItem(target_blob_uuid, blob_item)); | 328 new ShareableBlobDataItem(target_blob_uuid, blob_item)); |
(...skipping 19 matching lines...) Expand all Loading... | |
348 } | 348 } |
349 target_blob_builder->AppendSharedBlobItem( | 349 target_blob_builder->AppendSharedBlobItem( |
350 new ShareableBlobDataItem(target_blob_uuid, blob_item)); | 350 new ShareableBlobDataItem(target_blob_uuid, blob_item)); |
351 break; | 351 break; |
352 } | 352 } |
353 case DataElement::TYPE_BLOB: { | 353 case DataElement::TYPE_BLOB: { |
354 UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.Blob", | 354 UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.Blob", |
355 (length - offset) / 1024); | 355 (length - offset) / 1024); |
356 // We grab the handle to ensure it stays around while we copy it. | 356 // We grab the handle to ensure it stays around while we copy it. |
357 scoped_ptr<BlobDataHandle> src = | 357 scoped_ptr<BlobDataHandle> src = |
358 GetBlobDataFromUUID(data_element.blob_uuid()); | 358 GetBlobDataFromUUID(blob_item->data_element().blob_uuid()); |
359 if (src) { | 359 if (src) { |
360 BlobMapEntry* other_entry = | 360 BlobMapEntry* other_entry = |
361 blob_map_.find(data_element.blob_uuid())->second; | 361 blob_map_.find(blob_item->data_element().blob_uuid())->second; |
362 DCHECK(other_entry->data); | 362 DCHECK(other_entry->data); |
363 exceeded_memory = !AppendBlob(target_blob_uuid, *other_entry->data, | 363 exceeded_memory = !AppendBlob(target_blob_uuid, *other_entry->data, |
364 offset, length, target_blob_builder); | 364 offset, length, target_blob_builder); |
365 } | 365 } |
366 break; | 366 break; |
367 } | 367 } |
368 case DataElement::TYPE_DISK_CACHE_ENTRY: { | |
369 UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.CacheEntry", | |
370 (length - offset) / 1024); | |
371 target_blob_builder->AppendSharedBlobItem( | |
372 new ShareableBlobDataItem(target_blob_uuid, blob_item)); | |
373 break; | |
374 } | |
368 default: | 375 default: |
369 NOTREACHED(); | 376 NOTREACHED(); |
370 break; | 377 break; |
371 } | 378 } |
372 UMA_HISTOGRAM_COUNTS("Storage.Blob.StorageSizeAfterAppend", | 379 UMA_HISTOGRAM_COUNTS("Storage.Blob.StorageSizeAfterAppend", |
373 memory_usage_ / 1024); | 380 memory_usage_ / 1024); |
374 | 381 |
375 return !exceeded_memory; | 382 return !exceeded_memory; |
376 } | 383 } |
377 | 384 |
(...skipping 18 matching lines...) Expand all Loading... | |
396 } | 403 } |
397 | 404 |
398 for (; iter != items.end() && length > 0; ++iter) { | 405 for (; iter != items.end() && length > 0; ++iter) { |
399 scoped_refptr<ShareableBlobDataItem> shareable_item = iter->get(); | 406 scoped_refptr<ShareableBlobDataItem> shareable_item = iter->get(); |
400 const BlobDataItem& item = *(shareable_item->item()); | 407 const BlobDataItem& item = *(shareable_item->item()); |
401 uint64_t item_length = item.GetLength(); | 408 uint64_t item_length = item.GetLength(); |
402 DCHECK_GT(item_length, offset); | 409 DCHECK_GT(item_length, offset); |
403 uint64_t current_length = item_length - offset; | 410 uint64_t current_length = item_length - offset; |
404 uint64_t new_length = current_length > length ? length : current_length; | 411 uint64_t new_length = current_length > length ? length : current_length; |
405 | 412 |
406 bool reusing_blob_item = offset == 0 && new_length == item_length; | 413 // Always reuse disk cache entries, as they never have an offset or length. |
414 bool reusing_blob_item = | |
415 item.type() == DataElement::TYPE_DISK_CACHE_ENTRY || | |
416 (offset == 0 && new_length == item_length); | |
407 UMA_HISTOGRAM_BOOLEAN("Storage.Blob.ReusedItem", reusing_blob_item); | 417 UMA_HISTOGRAM_BOOLEAN("Storage.Blob.ReusedItem", reusing_blob_item); |
408 if (reusing_blob_item) { | 418 if (reusing_blob_item) { |
409 shareable_item->referencing_blobs().insert(target_blob_uuid); | 419 shareable_item->referencing_blobs().insert(target_blob_uuid); |
410 target_blob_builder->AppendSharedBlobItem(shareable_item); | 420 target_blob_builder->AppendSharedBlobItem(shareable_item); |
411 length -= new_length; | 421 length -= new_length; |
412 continue; | 422 continue; |
413 } | 423 } |
414 | 424 |
415 // We need to do copying of the items when we have a different offset or | 425 // We need to do copying of the items when we have a different offset or |
416 // length | 426 // length |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
470 if (found == blob_map_.end()) | 480 if (found == blob_map_.end()) |
471 return false; | 481 return false; |
472 return found->second->IsBeingBuilt(); | 482 return found->second->IsBeingBuilt(); |
473 } | 483 } |
474 | 484 |
475 bool BlobStorageContext::IsUrlRegistered(const GURL& blob_url) { | 485 bool BlobStorageContext::IsUrlRegistered(const GURL& blob_url) { |
476 return public_blob_urls_.find(blob_url) != public_blob_urls_.end(); | 486 return public_blob_urls_.find(blob_url) != public_blob_urls_.end(); |
477 } | 487 } |
478 | 488 |
479 } // namespace storage | 489 } // namespace storage |
OLD | NEW |