| 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 <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 283 switch (data_element.type()) { | 283 switch (data_element.type()) { |
| 284 case DataElement::TYPE_BYTES: | 284 case DataElement::TYPE_BYTES: |
| 285 UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.Bytes", length / 1024); | 285 UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.Bytes", length / 1024); |
| 286 DCHECK(!offset); | 286 DCHECK(!offset); |
| 287 if (memory_usage_ + length > kBlobStorageMaxMemoryUsage) { | 287 if (memory_usage_ + length > kBlobStorageMaxMemoryUsage) { |
| 288 error = true; | 288 error = true; |
| 289 *error_code = IPCBlobCreationCancelCode::OUT_OF_MEMORY; | 289 *error_code = IPCBlobCreationCancelCode::OUT_OF_MEMORY; |
| 290 break; | 290 break; |
| 291 } | 291 } |
| 292 memory_usage_ += length; | 292 memory_usage_ += length; |
| 293 target_blob_builder->AppendSharedBlobItem( | 293 target_blob_builder->AppendSharedBlobItem(new ShareableBlobDataItem( |
| 294 new ShareableBlobDataItem(target_blob_uuid, blob_item)); | 294 target_blob_uuid, blob_item, |
| 295 ShareableBlobDataItem::POPULATED_WITH_QUOTA)); |
| 295 break; | 296 break; |
| 296 case DataElement::TYPE_FILE: { | 297 case DataElement::TYPE_FILE: { |
| 297 bool full_file = (length == std::numeric_limits<uint64_t>::max()); | 298 bool full_file = (length == std::numeric_limits<uint64_t>::max()); |
| 298 UMA_HISTOGRAM_BOOLEAN("Storage.BlobItemSize.File.Unknown", full_file); | 299 UMA_HISTOGRAM_BOOLEAN("Storage.BlobItemSize.File.Unknown", full_file); |
| 299 if (!full_file) { | 300 if (!full_file) { |
| 300 UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.File", | 301 UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.File", |
| 301 (length - offset) / 1024); | 302 (length - offset) / 1024); |
| 302 } | 303 } |
| 303 target_blob_builder->AppendSharedBlobItem( | 304 target_blob_builder->AppendSharedBlobItem(new ShareableBlobDataItem( |
| 304 new ShareableBlobDataItem(target_blob_uuid, blob_item)); | 305 target_blob_uuid, blob_item, |
| 306 ShareableBlobDataItem::POPULATED_WITHOUT_QUOTA)); |
| 305 break; | 307 break; |
| 306 } | 308 } |
| 307 case DataElement::TYPE_FILE_FILESYSTEM: { | 309 case DataElement::TYPE_FILE_FILESYSTEM: { |
| 308 bool full_file = (length == std::numeric_limits<uint64_t>::max()); | 310 bool full_file = (length == std::numeric_limits<uint64_t>::max()); |
| 309 UMA_HISTOGRAM_BOOLEAN("Storage.BlobItemSize.FileSystem.Unknown", | 311 UMA_HISTOGRAM_BOOLEAN("Storage.BlobItemSize.FileSystem.Unknown", |
| 310 full_file); | 312 full_file); |
| 311 if (!full_file) { | 313 if (!full_file) { |
| 312 UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.FileSystem", | 314 UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.FileSystem", |
| 313 (length - offset) / 1024); | 315 (length - offset) / 1024); |
| 314 } | 316 } |
| 315 target_blob_builder->AppendSharedBlobItem( | 317 target_blob_builder->AppendSharedBlobItem(new ShareableBlobDataItem( |
| 316 new ShareableBlobDataItem(target_blob_uuid, blob_item)); | 318 target_blob_uuid, blob_item, |
| 319 ShareableBlobDataItem::POPULATED_WITHOUT_QUOTA)); |
| 317 break; | 320 break; |
| 318 } | 321 } |
| 319 case DataElement::TYPE_BLOB: { | 322 case DataElement::TYPE_BLOB: { |
| 320 UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.Blob", | 323 UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.Blob", |
| 321 (length - offset) / 1024); | 324 (length - offset) / 1024); |
| 322 // We grab the handle to ensure it stays around while we copy it. | 325 // We grab the handle to ensure it stays around while we copy it. |
| 323 std::unique_ptr<BlobDataHandle> src = | 326 std::unique_ptr<BlobDataHandle> src = |
| 324 GetBlobDataFromUUID(data_element.blob_uuid()); | 327 GetBlobDataFromUUID(data_element.blob_uuid()); |
| 325 if (!src || src->IsBroken() || src->IsBeingBuilt()) { | 328 if (!src || src->IsBroken() || src->IsBeingBuilt()) { |
| 326 error = true; | 329 error = true; |
| 327 *error_code = IPCBlobCreationCancelCode::REFERENCED_BLOB_BROKEN; | 330 *error_code = IPCBlobCreationCancelCode::REFERENCED_BLOB_BROKEN; |
| 328 break; | 331 break; |
| 329 } | 332 } |
| 330 BlobRegistryEntry* other_entry = | 333 BlobRegistryEntry* other_entry = |
| 331 registry_.GetEntry(data_element.blob_uuid()); | 334 registry_.GetEntry(data_element.blob_uuid()); |
| 332 DCHECK(other_entry->data); | 335 DCHECK(other_entry->data); |
| 333 if (!AppendBlob(target_blob_uuid, *other_entry->data, offset, length, | 336 if (!AppendBlob(target_blob_uuid, *other_entry->data, offset, length, |
| 334 target_blob_builder)) { | 337 target_blob_builder)) { |
| 335 error = true; | 338 error = true; |
| 336 *error_code = IPCBlobCreationCancelCode::OUT_OF_MEMORY; | 339 *error_code = IPCBlobCreationCancelCode::OUT_OF_MEMORY; |
| 337 } | 340 } |
| 338 break; | 341 break; |
| 339 } | 342 } |
| 340 case DataElement::TYPE_DISK_CACHE_ENTRY: { | 343 case DataElement::TYPE_DISK_CACHE_ENTRY: { |
| 341 UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.CacheEntry", | 344 UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.CacheEntry", |
| 342 (length - offset) / 1024); | 345 (length - offset) / 1024); |
| 343 target_blob_builder->AppendSharedBlobItem( | 346 target_blob_builder->AppendSharedBlobItem(new ShareableBlobDataItem( |
| 344 new ShareableBlobDataItem(target_blob_uuid, blob_item)); | 347 target_blob_uuid, blob_item, |
| 348 ShareableBlobDataItem::POPULATED_WITHOUT_QUOTA)); |
| 345 break; | 349 break; |
| 346 } | 350 } |
| 347 case DataElement::TYPE_BYTES_DESCRIPTION: | 351 case DataElement::TYPE_BYTES_DESCRIPTION: |
| 348 case DataElement::TYPE_UNKNOWN: | 352 case DataElement::TYPE_UNKNOWN: |
| 349 NOTREACHED(); | 353 NOTREACHED(); |
| 350 break; | 354 break; |
| 351 } | 355 } |
| 352 UMA_HISTOGRAM_COUNTS("Storage.Blob.StorageSizeAfterAppend", | 356 UMA_HISTOGRAM_COUNTS("Storage.Blob.StorageSizeAfterAppend", |
| 353 memory_usage_ / 1024); | 357 memory_usage_ / 1024); |
| 354 return !error; | 358 return !error; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 378 scoped_refptr<ShareableBlobDataItem> shareable_item = iter->get(); | 382 scoped_refptr<ShareableBlobDataItem> shareable_item = iter->get(); |
| 379 const BlobDataItem& item = *(shareable_item->item()); | 383 const BlobDataItem& item = *(shareable_item->item()); |
| 380 uint64_t item_length = item.length(); | 384 uint64_t item_length = item.length(); |
| 381 DCHECK_GT(item_length, offset); | 385 DCHECK_GT(item_length, offset); |
| 382 uint64_t current_length = item_length - offset; | 386 uint64_t current_length = item_length - offset; |
| 383 uint64_t new_length = current_length > length ? length : current_length; | 387 uint64_t new_length = current_length > length ? length : current_length; |
| 384 | 388 |
| 385 bool reusing_blob_item = offset == 0 && new_length == item.length(); | 389 bool reusing_blob_item = offset == 0 && new_length == item.length(); |
| 386 UMA_HISTOGRAM_BOOLEAN("Storage.Blob.ReusedItem", reusing_blob_item); | 390 UMA_HISTOGRAM_BOOLEAN("Storage.Blob.ReusedItem", reusing_blob_item); |
| 387 if (reusing_blob_item) { | 391 if (reusing_blob_item) { |
| 388 shareable_item->referencing_blobs().insert(target_blob_uuid); | 392 shareable_item->referencing_blobs_mutable()->insert(target_blob_uuid); |
| 389 target_blob_builder->AppendSharedBlobItem(shareable_item); | 393 target_blob_builder->AppendSharedBlobItem(shareable_item); |
| 390 length -= new_length; | 394 length -= new_length; |
| 391 continue; | 395 continue; |
| 392 } | 396 } |
| 393 | 397 |
| 394 // We need to do copying of the items when we have a different offset or | 398 // We need to do copying of the items when we have a different offset or |
| 395 // length | 399 // length |
| 396 switch (item.type()) { | 400 switch (item.type()) { |
| 397 case DataElement::TYPE_BYTES: { | 401 case DataElement::TYPE_BYTES: { |
| 398 UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.BlobSlice.Bytes", | 402 UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.BlobSlice.Bytes", |
| 399 new_length / 1024); | 403 new_length / 1024); |
| 400 if (memory_usage_ + new_length > kBlobStorageMaxMemoryUsage) { | 404 if (memory_usage_ + new_length > kBlobStorageMaxMemoryUsage) { |
| 401 return false; | 405 return false; |
| 402 } | 406 } |
| 403 DCHECK(!item.offset()); | 407 DCHECK(!item.offset()); |
| 404 std::unique_ptr<DataElement> element(new DataElement()); | 408 std::unique_ptr<DataElement> element(new DataElement()); |
| 405 element->SetToBytes(item.bytes() + offset, | 409 element->SetToBytes(item.bytes() + offset, |
| 406 static_cast<int64_t>(new_length)); | 410 static_cast<int64_t>(new_length)); |
| 407 memory_usage_ += new_length; | 411 memory_usage_ += new_length; |
| 408 target_blob_builder->AppendSharedBlobItem(new ShareableBlobDataItem( | 412 target_blob_builder->AppendSharedBlobItem(new ShareableBlobDataItem( |
| 409 target_blob_uuid, new BlobDataItem(std::move(element)))); | 413 target_blob_uuid, new BlobDataItem(std::move(element)), |
| 414 ShareableBlobDataItem::POPULATED_WITH_QUOTA)); |
| 410 } break; | 415 } break; |
| 411 case DataElement::TYPE_FILE: { | 416 case DataElement::TYPE_FILE: { |
| 412 DCHECK_NE(item.length(), std::numeric_limits<uint64_t>::max()) | 417 DCHECK_NE(item.length(), std::numeric_limits<uint64_t>::max()) |
| 413 << "We cannot use a section of a file with an unknown length"; | 418 << "We cannot use a section of a file with an unknown length"; |
| 414 UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.BlobSlice.File", | 419 UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.BlobSlice.File", |
| 415 new_length / 1024); | 420 new_length / 1024); |
| 416 std::unique_ptr<DataElement> element(new DataElement()); | 421 std::unique_ptr<DataElement> element(new DataElement()); |
| 417 element->SetToFilePathRange(item.path(), item.offset() + offset, | 422 element->SetToFilePathRange(item.path(), item.offset() + offset, |
| 418 new_length, | 423 new_length, |
| 419 item.expected_modification_time()); | 424 item.expected_modification_time()); |
| 420 target_blob_builder->AppendSharedBlobItem(new ShareableBlobDataItem( | 425 target_blob_builder->AppendSharedBlobItem(new ShareableBlobDataItem( |
| 421 target_blob_uuid, | 426 target_blob_uuid, |
| 422 new BlobDataItem(std::move(element), item.data_handle_))); | 427 new BlobDataItem(std::move(element), item.data_handle_), |
| 428 ShareableBlobDataItem::POPULATED_WITHOUT_QUOTA)); |
| 423 } break; | 429 } break; |
| 424 case DataElement::TYPE_FILE_FILESYSTEM: { | 430 case DataElement::TYPE_FILE_FILESYSTEM: { |
| 425 UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.BlobSlice.FileSystem", | 431 UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.BlobSlice.FileSystem", |
| 426 new_length / 1024); | 432 new_length / 1024); |
| 427 std::unique_ptr<DataElement> element(new DataElement()); | 433 std::unique_ptr<DataElement> element(new DataElement()); |
| 428 element->SetToFileSystemUrlRange(item.filesystem_url(), | 434 element->SetToFileSystemUrlRange(item.filesystem_url(), |
| 429 item.offset() + offset, new_length, | 435 item.offset() + offset, new_length, |
| 430 item.expected_modification_time()); | 436 item.expected_modification_time()); |
| 431 target_blob_builder->AppendSharedBlobItem(new ShareableBlobDataItem( | 437 target_blob_builder->AppendSharedBlobItem(new ShareableBlobDataItem( |
| 432 target_blob_uuid, new BlobDataItem(std::move(element)))); | 438 target_blob_uuid, new BlobDataItem(std::move(element)), |
| 439 ShareableBlobDataItem::POPULATED_WITHOUT_QUOTA)); |
| 433 } break; | 440 } break; |
| 434 case DataElement::TYPE_DISK_CACHE_ENTRY: { | 441 case DataElement::TYPE_DISK_CACHE_ENTRY: { |
| 435 std::unique_ptr<DataElement> element(new DataElement()); | 442 std::unique_ptr<DataElement> element(new DataElement()); |
| 436 element->SetToDiskCacheEntryRange(item.offset() + offset, | 443 element->SetToDiskCacheEntryRange(item.offset() + offset, |
| 437 new_length); | 444 new_length); |
| 438 target_blob_builder->AppendSharedBlobItem(new ShareableBlobDataItem( | 445 target_blob_builder->AppendSharedBlobItem(new ShareableBlobDataItem( |
| 439 target_blob_uuid, | 446 target_blob_uuid, |
| 440 new BlobDataItem(std::move(element), item.data_handle_, | 447 new BlobDataItem(std::move(element), item.data_handle_, |
| 441 item.disk_cache_entry(), | 448 item.disk_cache_entry(), |
| 442 item.disk_cache_stream_index(), | 449 item.disk_cache_stream_index(), |
| 443 item.disk_cache_side_stream_index()))); | 450 item.disk_cache_side_stream_index()), |
| 451 ShareableBlobDataItem::POPULATED_WITHOUT_QUOTA)); |
| 444 } break; | 452 } break; |
| 445 case DataElement::TYPE_BYTES_DESCRIPTION: | 453 case DataElement::TYPE_BYTES_DESCRIPTION: |
| 446 case DataElement::TYPE_BLOB: | 454 case DataElement::TYPE_BLOB: |
| 447 case DataElement::TYPE_UNKNOWN: | 455 case DataElement::TYPE_UNKNOWN: |
| 448 CHECK(false) << "Illegal blob item type: " << item.type(); | 456 CHECK(false) << "Illegal blob item type: " << item.type(); |
| 449 } | 457 } |
| 450 length -= new_length; | 458 length -= new_length; |
| 451 offset = 0; | 459 offset = 0; |
| 452 } | 460 } |
| 453 return true; | 461 return true; |
| 454 } | 462 } |
| 455 | 463 |
| 456 } // namespace storage | 464 } // namespace storage |
| OLD | NEW |