Chromium Code Reviews| Index: storage/browser/blob/blob_storage_context.cc |
| diff --git a/storage/browser/blob/blob_storage_context.cc b/storage/browser/blob/blob_storage_context.cc |
| index 6df7afdba9a7ccb65a487dbd70f6ba691f0bab25..c91971db0f4d46bb1060b8058c9ed00899a4c838 100644 |
| --- a/storage/browser/blob/blob_storage_context.cc |
| +++ b/storage/browser/blob/blob_storage_context.cc |
| @@ -11,111 +11,59 @@ |
| #include <utility> |
| #include "base/bind.h" |
| +#include "base/callback.h" |
| #include "base/location.h" |
| #include "base/logging.h" |
| #include "base/memory/scoped_ptr.h" |
| +#include "base/message_loop/message_loop.h" |
| #include "base/metrics/histogram.h" |
| -#include "base/stl_util.h" |
| #include "base/thread_task_runner_handle.h" |
| #include "base/trace_event/trace_event.h" |
| #include "storage/browser/blob/blob_data_builder.h" |
| -#include "storage/browser/blob/shareable_file_reference.h" |
| +#include "storage/browser/blob/blob_data_handle.h" |
| +#include "storage/browser/blob/blob_data_item.h" |
| +#include "storage/browser/blob/blob_data_snapshot.h" |
| +#include "storage/browser/blob/shareable_blob_data_item.h" |
| #include "url/gurl.h" |
| namespace storage { |
| +using BlobRegistryEntry = BlobStorageRegistry::Entry; |
| +using BlobState = BlobStorageRegistry::BlobState; |
| -namespace { |
| - |
| -// We can't use GURL directly for these hash fragment manipulations |
| -// since it doesn't have specific knowlege of the BlobURL format. GURL |
| -// treats BlobURLs as if they were PathURLs which don't support hash |
| -// fragments. |
| - |
| -bool BlobUrlHasRef(const GURL& url) { |
| - return url.spec().find('#') != std::string::npos; |
| -} |
| - |
| -GURL ClearBlobUrlRef(const GURL& url) { |
| - size_t hash_pos = url.spec().find('#'); |
| - if (hash_pos == std::string::npos) |
| - return url; |
| - return GURL(url.spec().substr(0, hash_pos)); |
| -} |
| - |
| -// TODO(michaeln): use base::SysInfo::AmountOfPhysicalMemoryMB() in some |
| -// way to come up with a better limit. |
| -static const int64_t kMaxMemoryUsage = 500 * 1024 * 1024; // Half a gig. |
| - |
| -} // namespace |
| - |
| -BlobStorageContext::BlobMapEntry::BlobMapEntry() : refcount(0), flags(0) { |
| -} |
| - |
| -BlobStorageContext::BlobMapEntry::BlobMapEntry(int refcount, |
| - InternalBlobData::Builder* data) |
| - : refcount(refcount), flags(0), data_builder(data) { |
| -} |
| - |
| -BlobStorageContext::BlobMapEntry::~BlobMapEntry() { |
| -} |
| - |
| -bool BlobStorageContext::BlobMapEntry::IsBeingBuilt() { |
| - return !!data_builder; |
| -} |
| - |
| -BlobStorageContext::BlobStorageContext() : memory_usage_(0) { |
| -} |
| +BlobStorageContext::BlobStorageContext() : memory_usage_(0) {} |
| BlobStorageContext::~BlobStorageContext() { |
| - STLDeleteContainerPairSecondPointers(blob_map_.begin(), blob_map_.end()); |
| } |
| scoped_ptr<BlobDataHandle> BlobStorageContext::GetBlobDataFromUUID( |
| const std::string& uuid) { |
| - scoped_ptr<BlobDataHandle> result; |
| - BlobMap::iterator found = blob_map_.find(uuid); |
| - if (found == blob_map_.end()) |
| - return result; |
| - auto* entry = found->second; |
| - if (entry->flags & EXCEEDED_MEMORY) |
| - return result; |
| - DCHECK(!entry->IsBeingBuilt()); |
| - result.reset(new BlobDataHandle(uuid, entry->data->content_type(), |
| - entry->data->content_disposition(), this, |
| - base::ThreadTaskRunnerHandle::Get().get())); |
| - return result; |
| + BlobRegistryEntry* entry = registry_.GetEntry(uuid); |
| + if (!entry) { |
| + return nullptr; |
| + } |
| + return make_scoped_ptr( |
| + new BlobDataHandle(uuid, entry->content_type, entry->content_disposition, |
| + this, base::ThreadTaskRunnerHandle::Get().get())); |
| } |
| scoped_ptr<BlobDataHandle> BlobStorageContext::GetBlobDataFromPublicURL( |
| const GURL& url) { |
| - BlobURLMap::iterator found = |
| - public_blob_urls_.find(BlobUrlHasRef(url) ? ClearBlobUrlRef(url) : url); |
| - if (found == public_blob_urls_.end()) |
| - return scoped_ptr<BlobDataHandle>(); |
| - return GetBlobDataFromUUID(found->second); |
| + std::string uuid; |
| + BlobRegistryEntry* entry = registry_.GetEntryFromURL(url, &uuid); |
| + if (!entry) { |
| + return nullptr; |
| + } |
| + return make_scoped_ptr( |
| + new BlobDataHandle(uuid, entry->content_type, entry->content_disposition, |
| + this, base::ThreadTaskRunnerHandle::Get().get())); |
| } |
| scoped_ptr<BlobDataHandle> BlobStorageContext::AddFinishedBlob( |
| const BlobDataBuilder& external_builder) { |
| TRACE_EVENT0("Blob", "Context::AddFinishedBlob"); |
| - StartBuildingBlob(external_builder.uuid_); |
| - BlobMap::iterator found = blob_map_.find(external_builder.uuid_); |
| - DCHECK(found != blob_map_.end()); |
| - BlobMapEntry* entry = found->second; |
| - InternalBlobData::Builder* target_blob_builder = entry->data_builder.get(); |
| - DCHECK(target_blob_builder); |
| - |
| - target_blob_builder->set_content_disposition( |
| - external_builder.content_disposition_); |
| - for (const auto& blob_item : external_builder.items_) { |
| - if (!AppendAllocatedBlobItem(external_builder.uuid_, blob_item, |
| - target_blob_builder)) { |
| - BlobEntryExceededMemory(entry); |
| - break; |
| - } |
| - } |
| - |
| - FinishBuildingBlob(external_builder.uuid_, external_builder.content_type_); |
| + CreatePendingBlob(external_builder.uuid(), external_builder.content_type_, |
| + external_builder.content_disposition_); |
| + CompletePendingBlob(external_builder); |
| scoped_ptr<BlobDataHandle> handle = |
| GetBlobDataFromUUID(external_builder.uuid_); |
| DecrementBlobRefCount(external_builder.uuid_); |
| @@ -130,185 +78,182 @@ scoped_ptr<BlobDataHandle> BlobStorageContext::AddFinishedBlob( |
| bool BlobStorageContext::RegisterPublicBlobURL(const GURL& blob_url, |
| const std::string& uuid) { |
| - DCHECK(!BlobUrlHasRef(blob_url)); |
| - DCHECK(IsInUse(uuid)); |
| - DCHECK(!IsUrlRegistered(blob_url)); |
| - if (!IsInUse(uuid) || IsUrlRegistered(blob_url)) |
| + if (!registry_.CreateUrlMapping(blob_url, uuid)) { |
| return false; |
| + } |
| IncrementBlobRefCount(uuid); |
| - public_blob_urls_[blob_url] = uuid; |
| return true; |
| } |
| void BlobStorageContext::RevokePublicBlobURL(const GURL& blob_url) { |
| - DCHECK(!BlobUrlHasRef(blob_url)); |
| - if (!IsUrlRegistered(blob_url)) |
| + std::string uuid; |
| + if (!registry_.DeleteURLMapping(blob_url, &uuid)) { |
| return; |
| - DecrementBlobRefCount(public_blob_urls_[blob_url]); |
| - public_blob_urls_.erase(blob_url); |
| -} |
| - |
| -scoped_ptr<BlobDataSnapshot> BlobStorageContext::CreateSnapshot( |
| - const std::string& uuid) { |
| - scoped_ptr<BlobDataSnapshot> result; |
| - auto found = blob_map_.find(uuid); |
| - DCHECK(found != blob_map_.end()) |
| - << "Blob " << uuid << " should be in map, as the handle is still around"; |
| - BlobMapEntry* entry = found->second; |
| - DCHECK(!entry->IsBeingBuilt()); |
| - const InternalBlobData& data = *entry->data; |
| - |
| - scoped_ptr<BlobDataSnapshot> snapshot(new BlobDataSnapshot( |
| - uuid, data.content_type(), data.content_disposition())); |
| - snapshot->items_.reserve(data.items().size()); |
| - for (const auto& shareable_item : data.items()) { |
| - snapshot->items_.push_back(shareable_item->item()); |
| } |
| - return snapshot; |
| -} |
| - |
| -void BlobStorageContext::StartBuildingBlob(const std::string& uuid) { |
| - DCHECK(!IsInUse(uuid) && !uuid.empty()); |
| - blob_map_[uuid] = new BlobMapEntry(1, new InternalBlobData::Builder()); |
| + DecrementBlobRefCount(uuid); |
| } |
| -void BlobStorageContext::AppendBlobDataItem( |
| +void BlobStorageContext::CreatePendingBlob( |
| const std::string& uuid, |
| - const storage::DataElement& ipc_data_element) { |
| - TRACE_EVENT0("Blob", "Context::AppendBlobDataItem"); |
| - DCHECK(IsBeingBuilt(uuid)); |
| - BlobMap::iterator found = blob_map_.find(uuid); |
| - if (found == blob_map_.end()) |
| - return; |
| - BlobMapEntry* entry = found->second; |
| - if (entry->flags & EXCEEDED_MEMORY) |
| - return; |
| - InternalBlobData::Builder* target_blob_builder = entry->data_builder.get(); |
| - DCHECK(target_blob_builder); |
| + const std::string& content_type, |
| + const std::string& content_disposition) { |
| + DCHECK(!registry_.GetEntry(uuid) && !uuid.empty()); |
| + registry_.CreateEntry(uuid, content_type, content_disposition); |
| +} |
| - if (ipc_data_element.type() == DataElement::TYPE_BYTES && |
| - memory_usage_ + ipc_data_element.length() > kMaxMemoryUsage) { |
| - BlobEntryExceededMemory(entry); |
| - return; |
| - } |
| - if (!AppendAllocatedBlobItem(uuid, AllocateBlobItem(uuid, ipc_data_element), |
| - target_blob_builder)) { |
| - BlobEntryExceededMemory(entry); |
| +void BlobStorageContext::CompletePendingBlob( |
| + const BlobDataBuilder& external_builder) { |
| + BlobRegistryEntry* entry = registry_.GetEntry(external_builder.uuid()); |
| + DCHECK(entry); |
| + DCHECK(!entry->data.get()) << "Blob already constructed: " |
| + << external_builder.uuid(); |
| + // We want to handle storing our broken blob as well. |
| + switch (entry->state) { |
| + case BlobState::PENDING: { |
| + entry->data_builder.reset(new InternalBlobData::Builder()); |
| + InternalBlobData::Builder* internal_data_builder = |
| + entry->data_builder.get(); |
| + |
| + bool broken = false; |
| + for (const auto& blob_item : external_builder.items_) { |
| + IPCBlobCreationCancelCode error_code; |
| + if (!AppendAllocatedBlobItem(external_builder.uuid_, blob_item, |
| + internal_data_builder, &error_code)) { |
| + broken = true; |
| + memory_usage_ -= entry->data_builder->GetNonsharedMemoryUsage(); |
| + entry->state = BlobState::BROKEN; |
| + entry->broken_reason = error_code; |
| + entry->data_builder.reset(new InternalBlobData::Builder()); |
| + break; |
| + } |
| + } |
| + entry->data = entry->data_builder->Build(); |
| + entry->data_builder.reset(); |
| + entry->state = broken ? BlobState::BROKEN : BlobState::COMPLETE; |
| + break; |
| + } |
| + case BlobState::BROKEN: { |
| + InternalBlobData::Builder builder; |
| + entry->data = builder.Build(); |
| + break; |
| + } |
| + case BlobState::COMPLETE: |
| + CHECK(false) << "Blob already constructed: " << external_builder.uuid(); |
|
michaeln
2016/02/23 02:25:41
can this be a dcheck?
dmurph
2016/02/23 23:45:31
Sure.
|
| + return; |
| } |
| -} |
| -void BlobStorageContext::FinishBuildingBlob(const std::string& uuid, |
| - const std::string& content_type) { |
| - DCHECK(IsBeingBuilt(uuid)); |
| - BlobMap::iterator found = blob_map_.find(uuid); |
| - if (found == blob_map_.end()) |
| - return; |
| - BlobMapEntry* entry = found->second; |
| - entry->data_builder->set_content_type(content_type); |
| - entry->data = entry->data_builder->Build(); |
| - entry->data_builder.reset(); |
| UMA_HISTOGRAM_COUNTS("Storage.Blob.ItemCount", entry->data->items().size()); |
| - UMA_HISTOGRAM_BOOLEAN("Storage.Blob.ExceededMemory", |
| - (entry->flags & EXCEEDED_MEMORY) == EXCEEDED_MEMORY); |
| + UMA_HISTOGRAM_BOOLEAN("Storage.Blob.Broken", |
| + entry->state == BlobState::BROKEN); |
| + UMA_HISTOGRAM_ENUMERATION( |
| + "Storage.Blob.BrokenReason", static_cast<int>(entry->broken_reason), |
| + (static_cast<int>(IPCBlobCreationCancelCode::LAST) + 1)); |
| size_t total_memory = 0, nonshared_memory = 0; |
| entry->data->GetMemoryUsage(&total_memory, &nonshared_memory); |
| UMA_HISTOGRAM_COUNTS("Storage.Blob.TotalSize", total_memory / 1024); |
| UMA_HISTOGRAM_COUNTS("Storage.Blob.TotalUnsharedSize", |
| nonshared_memory / 1024); |
| TRACE_COUNTER1("Blob", "MemoryStoreUsageBytes", memory_usage_); |
| + |
| + auto runner = base::ThreadTaskRunnerHandle::Get(); |
| + for (const auto& callback : entry->build_completion_callbacks) { |
| + runner->PostTask(FROM_HERE, |
| + base::Bind(callback, entry->state == BlobState::COMPLETE)); |
| + } |
| + entry->build_completion_callbacks.clear(); |
| } |
| -void BlobStorageContext::CancelBuildingBlob(const std::string& uuid) { |
| - DCHECK(IsBeingBuilt(uuid)); |
| - DecrementBlobRefCount(uuid); |
| +void BlobStorageContext::CancelPendingBlob(const std::string& uuid, |
| + IPCBlobCreationCancelCode reason) { |
| + BlobRegistryEntry* entry = registry_.GetEntry(uuid); |
| + DCHECK(entry && entry->state == BlobState::PENDING); |
| + entry->state = BlobState::BROKEN; |
| + entry->broken_reason = reason; |
| + CompletePendingBlob(BlobDataBuilder(uuid)); |
| } |
| void BlobStorageContext::IncrementBlobRefCount(const std::string& uuid) { |
| - BlobMap::iterator found = blob_map_.find(uuid); |
| - if (found == blob_map_.end()) { |
| - DCHECK(false); |
| - return; |
| - } |
| - ++(found->second->refcount); |
| + BlobRegistryEntry* entry = registry_.GetEntry(uuid); |
| + DCHECK(entry); |
| + ++(entry->refcount); |
| } |
| void BlobStorageContext::DecrementBlobRefCount(const std::string& uuid) { |
| - BlobMap::iterator found = blob_map_.find(uuid); |
| - if (found == blob_map_.end()) |
| - return; |
| - auto* entry = found->second; |
| + BlobRegistryEntry* entry = registry_.GetEntry(uuid); |
| + DCHECK(entry); |
| + DCHECK_GT(entry->refcount, 0u); |
| if (--(entry->refcount) == 0) { |
| size_t memory_freeing = 0; |
| - if (entry->IsBeingBuilt()) { |
| - memory_freeing = entry->data_builder->GetNonsharedMemoryUsage(); |
| - entry->data_builder->RemoveBlobFromShareableItems(uuid); |
| - } else { |
| + if (entry->state == BlobState::COMPLETE) { |
| memory_freeing = entry->data->GetUnsharedMemoryUsage(); |
| entry->data->RemoveBlobFromShareableItems(uuid); |
| } |
| DCHECK_LE(memory_freeing, memory_usage_); |
| memory_usage_ -= memory_freeing; |
| - delete entry; |
| - blob_map_.erase(found); |
| + registry_.DeleteEntry(uuid); |
| } |
| } |
| -void BlobStorageContext::BlobEntryExceededMemory(BlobMapEntry* entry) { |
| - // If we're using too much memory, drop this blob's data. |
| - // TODO(michaeln): Blob memory storage does not yet spill over to disk, |
| - // as a stop gap, we'll prevent memory usage over a max amount. |
| - memory_usage_ -= entry->data_builder->GetNonsharedMemoryUsage(); |
| - entry->flags |= EXCEEDED_MEMORY; |
| - entry->data_builder.reset(new InternalBlobData::Builder()); |
| +scoped_ptr<BlobDataSnapshot> BlobStorageContext::CreateSnapshot( |
| + const std::string& uuid) { |
| + scoped_ptr<BlobDataSnapshot> result; |
| + BlobRegistryEntry* entry = registry_.GetEntry(uuid); |
| + if (entry->state != BlobState::COMPLETE) { |
| + return result; |
| + } |
| + |
| + const InternalBlobData& data = *entry->data; |
| + scoped_ptr<BlobDataSnapshot> snapshot(new BlobDataSnapshot( |
| + uuid, entry->content_type, entry->content_disposition)); |
| + snapshot->items_.reserve(data.items().size()); |
| + for (const auto& shareable_item : data.items()) { |
| + snapshot->items_.push_back(shareable_item->item()); |
| + } |
| + return snapshot; |
| } |
| -scoped_refptr<BlobDataItem> BlobStorageContext::AllocateBlobItem( |
| - const std::string& uuid, |
| - const DataElement& ipc_data) { |
| - scoped_refptr<BlobDataItem> blob_item; |
| +bool BlobStorageContext::IsBroken(const std::string& uuid) const { |
| + const BlobRegistryEntry* entry = registry_.GetEntry(uuid); |
| + if (!entry) { |
| + return true; |
| + } |
| + return entry->state == BlobState::BROKEN; |
| +} |
| - uint64_t length = ipc_data.length(); |
| - scoped_ptr<DataElement> element(new DataElement()); |
| - switch (ipc_data.type()) { |
| - case DataElement::TYPE_BYTES: |
| - DCHECK(!ipc_data.offset()); |
| - element->SetToBytes(ipc_data.bytes(), length); |
| - blob_item = new BlobDataItem(std::move(element)); |
| - break; |
| - case DataElement::TYPE_FILE: |
| - element->SetToFilePathRange(ipc_data.path(), ipc_data.offset(), length, |
| - ipc_data.expected_modification_time()); |
| - blob_item = new BlobDataItem( |
| - std::move(element), ShareableFileReference::Get(ipc_data.path())); |
| - break; |
| - case DataElement::TYPE_FILE_FILESYSTEM: |
| - element->SetToFileSystemUrlRange(ipc_data.filesystem_url(), |
| - ipc_data.offset(), length, |
| - ipc_data.expected_modification_time()); |
| - blob_item = new BlobDataItem(std::move(element)); |
| - break; |
| - case DataElement::TYPE_BLOB: |
| - // This is a temporary item that will be deconstructed later. |
| - element->SetToBlobRange(ipc_data.blob_uuid(), ipc_data.offset(), |
| - ipc_data.length()); |
| - blob_item = new BlobDataItem(std::move(element)); |
| - break; |
| - case DataElement::TYPE_DISK_CACHE_ENTRY: // This type can't be sent by IPC. |
| - NOTREACHED(); |
| - break; |
| - default: |
| - NOTREACHED(); |
| - break; |
| +bool BlobStorageContext::IsBeingBuilt(const std::string& uuid) const { |
| + const BlobRegistryEntry* entry = registry_.GetEntry(uuid); |
| + if (!entry) { |
| + return false; |
| } |
| + return entry->state == BlobState::PENDING; |
| +} |
| - return blob_item; |
| +void BlobStorageContext::RunOnConstructionComplete( |
| + const std::string& uuid, |
| + const base::Callback<void(bool)>& done) { |
| + BlobRegistryEntry* entry = registry_.GetEntry(uuid); |
| + DCHECK(entry); |
| + switch (entry->state) { |
| + case BlobState::COMPLETE: |
| + done.Run(true); |
| + return; |
| + case BlobState::BROKEN: |
| + done.Run(false); |
| + return; |
| + case BlobState::PENDING: |
| + entry->build_completion_callbacks.push_back(done); |
| + return; |
| + } |
| + NOTREACHED(); |
| } |
| bool BlobStorageContext::AppendAllocatedBlobItem( |
| const std::string& target_blob_uuid, |
| scoped_refptr<BlobDataItem> blob_item, |
| - InternalBlobData::Builder* target_blob_builder) { |
| - bool exceeded_memory = false; |
| + InternalBlobData::Builder* target_blob_builder, |
| + IPCBlobCreationCancelCode* error_code) { |
| + DCHECK(error_code); |
| + bool error = false; |
|
michaeln
2016/02/23 02:25:41
maybe set *error_code to noerror for safety?
dmurph
2016/02/23 23:45:31
That type doesn't exist. I'll do UNKNOWN.
|
| // The blob data is stored in the canonical way which only contains a |
| // list of Data, File, and FileSystem items. Aggregated TYPE_BLOB items |
| @@ -323,6 +268,7 @@ bool BlobStorageContext::AppendAllocatedBlobItem( |
| // offset or size) are shared between the blobs. Otherwise, the relevant |
| // portion of the item is copied. |
| + DCHECK(blob_item->data_element_ptr()); |
| const DataElement& data_element = blob_item->data_element(); |
| uint64_t length = data_element.length(); |
| uint64_t offset = data_element.offset(); |
| @@ -332,8 +278,9 @@ bool BlobStorageContext::AppendAllocatedBlobItem( |
| case DataElement::TYPE_BYTES: |
| UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.Bytes", length / 1024); |
| DCHECK(!offset); |
| - if (memory_usage_ + length > kMaxMemoryUsage) { |
| - exceeded_memory = true; |
| + if (memory_usage_ + length > kBlobStorageMaxMemoryUsage) { |
| + error = true; |
| + *error_code = IPCBlobCreationCancelCode::OUT_OF_MEMORY; |
| break; |
| } |
| memory_usage_ += length; |
| @@ -369,12 +316,23 @@ bool BlobStorageContext::AppendAllocatedBlobItem( |
| // We grab the handle to ensure it stays around while we copy it. |
| scoped_ptr<BlobDataHandle> src = |
| GetBlobDataFromUUID(data_element.blob_uuid()); |
| + // We don't error on an unknown blob, and instead ignore it. Perhaps we |
| + // shouldn't do this. It shouldn't happen if everything is working |
| + // properly, unless we have a wonky renderer. |
| if (src) { |
| - BlobMapEntry* other_entry = |
| - blob_map_.find(data_element.blob_uuid())->second; |
| + if (src->IsBroken() || src->IsBeingBuilt()) { |
|
michaeln
2016/02/23 02:25:41
IsBeingBuilt() would be very unexpected here, unre
dmurph
2016/02/23 23:45:31
It can be reached if someone in browserland is cre
|
| + error = true; |
| + *error_code = IPCBlobCreationCancelCode::REFERENCED_BLOB_BROKEN; |
| + break; |
| + } |
| + BlobRegistryEntry* other_entry = |
| + registry_.GetEntry(data_element.blob_uuid()); |
| DCHECK(other_entry->data); |
| - exceeded_memory = !AppendBlob(target_blob_uuid, *other_entry->data, |
| - offset, length, target_blob_builder); |
| + if (!AppendBlob(target_blob_uuid, *other_entry->data, offset, length, |
| + target_blob_builder)) { |
| + error = true; |
| + *error_code = IPCBlobCreationCancelCode::OUT_OF_MEMORY; |
| + } |
| } |
| break; |
| } |
| @@ -385,14 +343,14 @@ bool BlobStorageContext::AppendAllocatedBlobItem( |
| new ShareableBlobDataItem(target_blob_uuid, blob_item)); |
| break; |
| } |
| - default: |
| + case DataElement::TYPE_BYTES_DESCRIPTION: |
| + case DataElement::TYPE_UNKNOWN: |
| NOTREACHED(); |
| break; |
| } |
| UMA_HISTOGRAM_COUNTS("Storage.Blob.StorageSizeAfterAppend", |
| memory_usage_ / 1024); |
| - |
| - return !exceeded_memory; |
| + return !error; |
| } |
| bool BlobStorageContext::AppendBlob( |
| @@ -401,7 +359,7 @@ bool BlobStorageContext::AppendBlob( |
| uint64_t offset, |
| uint64_t length, |
| InternalBlobData::Builder* target_blob_builder) { |
| - DCHECK(length > 0); |
| + DCHECK_GT(length, 0ull); |
| const std::vector<scoped_refptr<ShareableBlobDataItem>>& items = blob.items(); |
| auto iter = items.begin(); |
| @@ -438,7 +396,7 @@ bool BlobStorageContext::AppendBlob( |
| case DataElement::TYPE_BYTES: { |
| UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.BlobSlice.Bytes", |
| new_length / 1024); |
| - if (memory_usage_ + new_length > kMaxMemoryUsage) { |
| + if (memory_usage_ + new_length > kBlobStorageMaxMemoryUsage) { |
| return false; |
| } |
| DCHECK(!item.offset()); |
| @@ -482,7 +440,9 @@ bool BlobStorageContext::AppendBlob( |
| item.disk_cache_entry(), |
| item.disk_cache_stream_index()))); |
| } break; |
| - default: |
| + case DataElement::TYPE_BYTES_DESCRIPTION: |
| + case DataElement::TYPE_BLOB: |
| + case DataElement::TYPE_UNKNOWN: |
| CHECK(false) << "Illegal blob item type: " << item.type(); |
| } |
| length -= new_length; |
| @@ -491,19 +451,4 @@ bool BlobStorageContext::AppendBlob( |
| return true; |
| } |
| -bool BlobStorageContext::IsInUse(const std::string& uuid) { |
| - return blob_map_.find(uuid) != blob_map_.end(); |
| -} |
| - |
| -bool BlobStorageContext::IsBeingBuilt(const std::string& uuid) { |
| - BlobMap::iterator found = blob_map_.find(uuid); |
| - if (found == blob_map_.end()) |
| - return false; |
| - return found->second->IsBeingBuilt(); |
| -} |
| - |
| -bool BlobStorageContext::IsUrlRegistered(const GURL& blob_url) { |
| - return public_blob_urls_.find(blob_url) != public_blob_urls_.end(); |
| -} |
| - |
| } // namespace storage |