Chromium Code Reviews| 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_)); | |
| 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: | |
| 287 NOTREACHED(); // XYZZY figer this out | |
| 288 break; | |
| 286 default: | 289 default: |
| 287 NOTREACHED(); | 290 NOTREACHED(); |
| 288 break; | 291 break; |
| 289 } | 292 } |
| 290 | 293 |
| 291 return blob_item; | 294 return blob_item; |
| 292 } | 295 } |
| 293 | 296 |
| 294 bool BlobStorageContext::AppendAllocatedBlobItem( | 297 bool BlobStorageContext::AppendAllocatedBlobItem( |
| 295 const std::string& target_blob_uuid, | 298 const std::string& target_blob_uuid, |
| 296 scoped_refptr<BlobDataItem> blob_item, | 299 scoped_refptr<BlobDataItem> blob_item, |
| 297 InternalBlobData::Builder* target_blob_builder) { | 300 InternalBlobData::Builder* target_blob_builder) { |
| 298 bool exceeded_memory = false; | 301 bool exceeded_memory = false; |
| 299 | 302 |
| 300 // The blob data is stored in the canonical way which only contains a | 303 // 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 | 304 // list of Data, File, and FileSystem items. Aggregated TYPE_BLOB items |
| 302 // are expanded into the primitive constituent types and reused if possible. | 305 // are expanded into the primitive constituent types and reused if possible. |
| 303 // 1) The Data item is denoted by the raw data and length. | 306 // 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 | 307 // 2) The File item is denoted by the file path, the range and the expected |
| 305 // modification time. | 308 // modification time. |
| 306 // 3) The FileSystem File item is denoted by the FileSystem URL, the range | 309 // 3) The FileSystem File item is denoted by the FileSystem URL, the range |
| 307 // and the expected modification time. | 310 // and the expected modification time. |
| 308 // 4) The Blob item is denoted by the source blob and an offset and size. | 311 // 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 | 312 // 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 | 313 // offset or size) are shared between the blobs. Otherwise, the relevant |
| 311 // portion of the item is copied. | 314 // portion of the item is copied. |
| 312 | 315 |
| 313 const DataElement& data_element = blob_item->data_element(); | 316 uint64 length = blob_item->GetLength(); |
| 314 uint64 length = data_element.length(); | 317 uint64 offset = blob_item->GetOffset(); |
| 315 uint64 offset = data_element.offset(); | |
| 316 UMA_HISTOGRAM_COUNTS("Storage.Blob.StorageSizeBeforeAppend", | 318 UMA_HISTOGRAM_COUNTS("Storage.Blob.StorageSizeBeforeAppend", |
| 317 memory_usage_ / 1024); | 319 memory_usage_ / 1024); |
| 318 switch (data_element.type()) { | 320 switch (blob_item->data_element().type()) { |
| 319 case DataElement::TYPE_BYTES: | 321 case DataElement::TYPE_BYTES: |
| 320 UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.Bytes", length / 1024); | 322 UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.Bytes", length / 1024); |
| 321 DCHECK(!offset); | 323 DCHECK(!offset); |
| 322 if (memory_usage_ + length > kMaxMemoryUsage) { | 324 if (memory_usage_ + length > kMaxMemoryUsage) { |
| 323 exceeded_memory = true; | 325 exceeded_memory = true; |
| 324 break; | 326 break; |
| 325 } | 327 } |
| 326 memory_usage_ += length; | 328 memory_usage_ += length; |
| 327 target_blob_builder->AppendSharedBlobItem( | 329 target_blob_builder->AppendSharedBlobItem( |
| 328 new ShareableBlobDataItem(target_blob_uuid, blob_item)); | 330 new ShareableBlobDataItem(target_blob_uuid, blob_item)); |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 348 } | 350 } |
| 349 target_blob_builder->AppendSharedBlobItem( | 351 target_blob_builder->AppendSharedBlobItem( |
| 350 new ShareableBlobDataItem(target_blob_uuid, blob_item)); | 352 new ShareableBlobDataItem(target_blob_uuid, blob_item)); |
| 351 break; | 353 break; |
| 352 } | 354 } |
| 353 case DataElement::TYPE_BLOB: { | 355 case DataElement::TYPE_BLOB: { |
| 354 UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.Blob", | 356 UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.Blob", |
| 355 (length - offset) / 1024); | 357 (length - offset) / 1024); |
| 356 // We grab the handle to ensure it stays around while we copy it. | 358 // We grab the handle to ensure it stays around while we copy it. |
| 357 scoped_ptr<BlobDataHandle> src = | 359 scoped_ptr<BlobDataHandle> src = |
| 358 GetBlobDataFromUUID(data_element.blob_uuid()); | 360 GetBlobDataFromUUID(blob_item->data_element().blob_uuid()); |
| 359 if (src) { | 361 if (src) { |
| 360 BlobMapEntry* other_entry = | 362 BlobMapEntry* other_entry = |
| 361 blob_map_.find(data_element.blob_uuid())->second; | 363 blob_map_.find(blob_item->data_element().blob_uuid())->second; |
| 362 DCHECK(other_entry->data); | 364 DCHECK(other_entry->data); |
| 363 exceeded_memory = !AppendBlob(target_blob_uuid, *other_entry->data, | 365 exceeded_memory = !AppendBlob(target_blob_uuid, *other_entry->data, |
| 364 offset, length, target_blob_builder); | 366 offset, length, target_blob_builder); |
| 365 } | 367 } |
| 366 break; | 368 break; |
| 367 } | 369 } |
| 370 case DataElement::TYPE_DISK_CACHE_ENTRY: { | |
| 371 UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.CacheEntry", | |
| 372 (length - offset) / 1024); | |
| 373 target_blob_builder->AppendSharedBlobItem( | |
| 374 new ShareableBlobDataItem(target_blob_uuid, blob_item)); | |
| 375 break; | |
| 376 } | |
| 368 default: | 377 default: |
| 369 NOTREACHED(); | 378 NOTREACHED(); |
| 370 break; | 379 break; |
| 371 } | 380 } |
| 372 UMA_HISTOGRAM_COUNTS("Storage.Blob.StorageSizeAfterAppend", | 381 UMA_HISTOGRAM_COUNTS("Storage.Blob.StorageSizeAfterAppend", |
| 373 memory_usage_ / 1024); | 382 memory_usage_ / 1024); |
| 374 | 383 |
| 375 return !exceeded_memory; | 384 return !exceeded_memory; |
| 376 } | 385 } |
| 377 | 386 |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 445 case DataElement::TYPE_FILE_FILESYSTEM: { | 454 case DataElement::TYPE_FILE_FILESYSTEM: { |
| 446 UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.BlobSlice.FileSystem", | 455 UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.BlobSlice.FileSystem", |
| 447 new_length / 1024); | 456 new_length / 1024); |
| 448 scoped_ptr<DataElement> element(new DataElement()); | 457 scoped_ptr<DataElement> element(new DataElement()); |
| 449 element->SetToFileSystemUrlRange(item.filesystem_url(), | 458 element->SetToFileSystemUrlRange(item.filesystem_url(), |
| 450 item.offset() + offset, new_length, | 459 item.offset() + offset, new_length, |
| 451 item.expected_modification_time()); | 460 item.expected_modification_time()); |
| 452 target_blob_builder->AppendSharedBlobItem(new ShareableBlobDataItem( | 461 target_blob_builder->AppendSharedBlobItem(new ShareableBlobDataItem( |
| 453 target_blob_uuid, new BlobDataItem(element.Pass()))); | 462 target_blob_uuid, new BlobDataItem(element.Pass()))); |
| 454 } break; | 463 } break; |
| 464 case DataElement::TYPE_DISK_CACHE_ENTRY: | |
| 465 CHECK(false) << "Can't append one of these yo"; | |
|
michaeln
2015/06/12 22:35:09
what's to prevent this?
cache.match(x).then(funct
| |
| 466 | |
| 455 default: | 467 default: |
| 456 CHECK(false) << "Illegal blob item type: " << item.type(); | 468 CHECK(false) << "Illegal blob item type: " << item.type(); |
| 457 } | 469 } |
| 458 length -= new_length; | 470 length -= new_length; |
| 459 offset = 0; | 471 offset = 0; |
| 460 } | 472 } |
| 461 return true; | 473 return true; |
| 462 } | 474 } |
| 463 | 475 |
| 464 bool BlobStorageContext::IsInUse(const std::string& uuid) { | 476 bool BlobStorageContext::IsInUse(const std::string& uuid) { |
| 465 return blob_map_.find(uuid) != blob_map_.end(); | 477 return blob_map_.find(uuid) != blob_map_.end(); |
| 466 } | 478 } |
| 467 | 479 |
| 468 bool BlobStorageContext::IsBeingBuilt(const std::string& uuid) { | 480 bool BlobStorageContext::IsBeingBuilt(const std::string& uuid) { |
| 469 BlobMap::iterator found = blob_map_.find(uuid); | 481 BlobMap::iterator found = blob_map_.find(uuid); |
| 470 if (found == blob_map_.end()) | 482 if (found == blob_map_.end()) |
| 471 return false; | 483 return false; |
| 472 return found->second->IsBeingBuilt(); | 484 return found->second->IsBeingBuilt(); |
| 473 } | 485 } |
| 474 | 486 |
| 475 bool BlobStorageContext::IsUrlRegistered(const GURL& blob_url) { | 487 bool BlobStorageContext::IsUrlRegistered(const GURL& blob_url) { |
| 476 return public_blob_urls_.find(blob_url) != public_blob_urls_.end(); | 488 return public_blob_urls_.find(blob_url) != public_blob_urls_.end(); |
| 477 } | 489 } |
| 478 | 490 |
| 479 } // namespace storage | 491 } // namespace storage |
| OLD | NEW |