Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(312)

Unified Diff: content/browser/cache_storage/cache_storage_cache.cc

Issue 1248003004: CacheStorage: Implement Cache.matchAll() (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix wrong conditional branch Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/cache_storage/cache_storage_cache.cc
diff --git a/content/browser/cache_storage/cache_storage_cache.cc b/content/browser/cache_storage/cache_storage_cache.cc
index b5da1119e1a99cbfe67d259726b2ed37e8d95b88..95974fa4bed5a074cd11317ae637db39c16a5322 100644
--- a/content/browser/cache_storage/cache_storage_cache.cc
+++ b/content/browser/cache_storage/cache_storage_cache.cc
@@ -176,34 +176,83 @@ void ReadMetadataDidReadMetadata(
callback.Run(metadata.Pass());
}
+void PopulateServiceWorkerResponse(const CacheMetadata& metadata,
jkarlin 2015/08/05 12:09:05 Perhaps rename to PopularResponseMetadata or Popul
nhiroki 2015/08/06 03:36:53 Good point. Renamed this.
+ ServiceWorkerResponse* response) {
+ *response = ServiceWorkerResponse(
+ GURL(metadata.response().url()), metadata.response().status_code(),
+ metadata.response().status_text(),
+ ProtoResponseTypeToWebResponseType(metadata.response().response_type()),
+ ServiceWorkerHeaderMap(), "", 0, GURL(),
+ blink::WebServiceWorkerResponseErrorUnknown);
+
+ for (int i = 0; i < metadata.response().headers_size(); ++i) {
+ const CacheHeaderMap header = metadata.response().headers(i);
+ DCHECK_EQ(std::string::npos, header.name().find('\0'));
+ DCHECK_EQ(std::string::npos, header.value().find('\0'));
+ response->headers.insert(std::make_pair(header.name(), header.value()));
+ }
+}
+
} // namespace
+// The state needed to iterate all entries in the cache.
+struct CacheStorageCache::OpenAllEntriesContext {
+ OpenAllEntriesContext() : enumerated_entry(nullptr) {}
+ ~OpenAllEntriesContext() {
+ for (size_t i = 0, max = entries.size(); i < max; ++i) {
+ if (entries[i])
+ entries[i]->Close();
+ if (enumerated_entry)
jkarlin 2015/08/05 12:09:05 Why is this in the for loop now?
nhiroki 2015/08/06 03:36:53 Oh..., this is just a mistake. Fixed. Thanks!
+ enumerated_entry->Close();
+ }
+ }
+
+ // The vector of open entries in the backend.
+ Entries entries;
+
+ // Used for enumerating cache entries.
+ scoped_ptr<disk_cache::Backend::Iterator> backend_iterator;
+ disk_cache::Entry* enumerated_entry;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(OpenAllEntriesContext);
+};
+
+// The state needed to pass between CacheStorageCache::MatchAll callbacks.
+struct CacheStorageCache::MatchAllContext {
+ explicit MatchAllContext(const CacheStorageCache::ResponsesCallback& callback)
+ : original_callback(callback) {}
+ ~MatchAllContext() {}
+
+ // The callback passed to the MatchAll() function.
+ CacheStorageCache::ResponsesCallback original_callback;
+
+ // The outputs of the MatchAll function.
+ std::vector<ServiceWorkerResponse> out_responses;
jkarlin 2015/08/05 12:09:05 scoped_ptr<std::vector<ServiceWorkerResponse>> to
nhiroki 2015/08/06 03:36:53 Done.
+ ScopedVector<storage::BlobDataHandle> out_blob_data_handles;
+
+ // The context holding open entries.
+ scoped_ptr<OpenAllEntriesContext> entries_context;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MatchAllContext);
+};
+
// The state needed to pass between CacheStorageCache::Keys callbacks.
struct CacheStorageCache::KeysContext {
explicit KeysContext(const CacheStorageCache::RequestsCallback& callback)
: original_callback(callback),
- out_keys(new CacheStorageCache::Requests()),
- enumerated_entry(NULL) {}
-
- ~KeysContext() {
- for (size_t i = 0, max = entries.size(); i < max; ++i)
- entries[i]->Close();
- if (enumerated_entry)
- enumerated_entry->Close();
- }
+ out_keys(new CacheStorageCache::Requests()) {}
+ ~KeysContext() {}
// The callback passed to the Keys() function.
CacheStorageCache::RequestsCallback original_callback;
- // The vector of open entries in the backend.
- Entries entries;
-
// The output of the Keys function.
scoped_ptr<CacheStorageCache::Requests> out_keys;
- // Used for enumerating cache entries.
- scoped_ptr<disk_cache::Backend::Iterator> backend_iterator;
- disk_cache::Entry* enumerated_entry;
+ // The context holding open entries.
+ scoped_ptr<OpenAllEntriesContext> entries_context;
private:
DISALLOW_COPY_AND_ASSIGN(KeysContext);
@@ -287,6 +336,22 @@ void CacheStorageCache::Match(scoped_ptr<ServiceWorkerFetchRequest> request,
base::Passed(request.Pass()), pending_callback));
}
+void CacheStorageCache::MatchAll(const ResponsesCallback& callback) {
+ if (!LazyInitialize()) {
+ callback.Run(CACHE_STORAGE_ERROR_STORAGE,
+ std::vector<ServiceWorkerResponse>(),
+ ScopedVector<storage::BlobDataHandle>());
+ return;
+ }
+
+ ResponsesCallback pending_callback =
+ base::Bind(&CacheStorageCache::PendingResponsesCallback,
+ weak_ptr_factory_.GetWeakPtr(), callback);
+ scheduler_->ScheduleOperation(base::Bind(&CacheStorageCache::MatchAllImpl,
+ weak_ptr_factory_.GetWeakPtr(),
+ pending_callback));
+}
+
void CacheStorageCache::BatchOperation(
const std::vector<CacheStorageBatchOperation>& operations,
const ErrorCallback& callback) {
@@ -432,6 +497,60 @@ bool CacheStorageCache::LazyInitialize() {
return false;
}
+void CacheStorageCache::OpenAllEntries(const OpenAllEntriesCallback& callback) {
+ scoped_ptr<OpenAllEntriesContext> entries_context(new OpenAllEntriesContext);
+ entries_context->backend_iterator = backend_->CreateIterator();
+ disk_cache::Backend::Iterator& iterator = *entries_context->backend_iterator;
+ disk_cache::Entry** enumerated_entry = &entries_context->enumerated_entry;
+
+ net::CompletionCallback open_entry_callback = base::Bind(
+ &CacheStorageCache::DidOpenNextEntry, weak_ptr_factory_.GetWeakPtr(),
+ base::Passed(entries_context.Pass()), callback);
+
+ int rv = iterator.OpenNextEntry(enumerated_entry, open_entry_callback);
+
+ if (rv != net::ERR_IO_PENDING)
+ open_entry_callback.Run(rv);
+}
+
+void CacheStorageCache::DidOpenNextEntry(
+ scoped_ptr<OpenAllEntriesContext> entries_context,
+ const OpenAllEntriesCallback& callback,
+ int rv) {
+ if (rv == net::ERR_FAILED) {
+ DCHECK(!entries_context->enumerated_entry);
+ // Enumeration is complete, extract the requests from the entries.
+ callback.Run(entries_context.Pass(), CACHE_STORAGE_OK);
+ return;
+ }
+
+ if (rv < 0) {
+ callback.Run(entries_context.Pass(), CACHE_STORAGE_ERROR_STORAGE);
+ return;
+ }
+
+ if (backend_state_ != BACKEND_OPEN) {
+ callback.Run(entries_context.Pass(), CACHE_STORAGE_ERROR_NOT_FOUND);
+ return;
+ }
+
+ // Store the entry.
+ entries_context->entries.push_back(entries_context->enumerated_entry);
+ entries_context->enumerated_entry = nullptr;
+
+ // Enumerate the next entry.
+ disk_cache::Backend::Iterator& iterator = *entries_context->backend_iterator;
+ disk_cache::Entry** enumerated_entry = &entries_context->enumerated_entry;
+ net::CompletionCallback open_entry_callback = base::Bind(
+ &CacheStorageCache::DidOpenNextEntry, weak_ptr_factory_.GetWeakPtr(),
+ base::Passed(entries_context.Pass()), callback);
+
+ rv = iterator.OpenNextEntry(enumerated_entry, open_entry_callback);
+
+ if (rv != net::ERR_IO_PENDING)
+ open_entry_callback.Run(rv);
+}
+
void CacheStorageCache::MatchImpl(scoped_ptr<ServiceWorkerFetchRequest> request,
const ResponseCallback& callback) {
DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_);
@@ -489,22 +608,8 @@ void CacheStorageCache::MatchDidReadMetadata(
return;
}
- scoped_ptr<ServiceWorkerResponse> response(new ServiceWorkerResponse(
- request->url, metadata->response().status_code(),
- metadata->response().status_text(),
- ProtoResponseTypeToWebResponseType(metadata->response().response_type()),
- ServiceWorkerHeaderMap(), "", 0, GURL(),
- blink::WebServiceWorkerResponseErrorUnknown));
-
- if (metadata->response().has_url())
- response->url = GURL(metadata->response().url());
-
- for (int i = 0; i < metadata->response().headers_size(); ++i) {
- const CacheHeaderMap header = metadata->response().headers(i);
- DCHECK_EQ(std::string::npos, header.name().find('\0'));
- DCHECK_EQ(std::string::npos, header.value().find('\0'));
- response->headers.insert(std::make_pair(header.name(), header.value()));
- }
+ scoped_ptr<ServiceWorkerResponse> response(new ServiceWorkerResponse);
+ PopulateServiceWorkerResponse(*metadata, response.get());
ServiceWorkerHeaderMap cached_request_headers;
for (int i = 0; i < metadata->request().headers_size(); ++i) {
@@ -549,6 +654,99 @@ void CacheStorageCache::MatchDidReadMetadata(
callback.Run(CACHE_STORAGE_OK, response.Pass(), blob_data_handle.Pass());
}
+void CacheStorageCache::MatchAllImpl(const ResponsesCallback& callback) {
+ DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_);
+ if (backend_state_ != BACKEND_OPEN) {
+ callback.Run(CACHE_STORAGE_ERROR_STORAGE,
+ std::vector<ServiceWorkerResponse>(),
+ ScopedVector<storage::BlobDataHandle>());
+ return;
+ }
+
+ OpenAllEntries(base::Bind(&CacheStorageCache::MatchAllDidOpenAllEntries,
+ weak_ptr_factory_.GetWeakPtr(), callback));
+}
+
+void CacheStorageCache::MatchAllDidOpenAllEntries(
+ const ResponsesCallback& callback,
+ scoped_ptr<OpenAllEntriesContext> entries_context,
+ CacheStorageError error) {
+ if (error != CACHE_STORAGE_OK) {
+ callback.Run(error, std::vector<ServiceWorkerResponse>(),
+ ScopedVector<storage::BlobDataHandle>());
+ return;
+ }
+
+ scoped_ptr<MatchAllContext> context(new MatchAllContext(callback));
+ context->entries_context.swap(entries_context);
+ Entries::iterator iter = context->entries_context->entries.begin();
+ MatchAllProcessNextEntry(context.Pass(), iter);
+}
+
+void CacheStorageCache::MatchAllProcessNextEntry(
+ scoped_ptr<MatchAllContext> context,
+ const Entries::iterator& iter) {
+ if (iter == context->entries_context->entries.end()) {
+ // All done. Return all of the responses.
+ context->original_callback.Run(CACHE_STORAGE_OK, context->out_responses,
+ context->out_blob_data_handles.Pass());
+ return;
+ }
+
+ ReadMetadata(*iter, base::Bind(&CacheStorageCache::MatchAllDidReadMetadata,
+ weak_ptr_factory_.GetWeakPtr(),
+ base::Passed(context.Pass()), iter));
+}
+
+void CacheStorageCache::MatchAllDidReadMetadata(
+ scoped_ptr<MatchAllContext> context,
+ const Entries::iterator& iter,
+ scoped_ptr<CacheMetadata> metadata) {
+ // Move ownership of the entry from the context.
+ disk_cache::ScopedEntryPtr entry(*iter);
+ *iter = nullptr;
+
+ if (!metadata) {
+ entry->Doom();
+ MatchAllProcessNextEntry(context.Pass(), iter + 1);
+ return;
+ }
+
+ ServiceWorkerResponse response;
+ PopulateServiceWorkerResponse(*metadata, &response);
+
+ if (entry->GetDataSize(INDEX_RESPONSE_BODY) == 0) {
+ context->out_responses.push_back(response);
+ context->out_blob_data_handles.push_back(nullptr);
+ MatchAllProcessNextEntry(context.Pass(), iter + 1);
+ return;
+ }
+
+ if (!blob_storage_context_) {
+ context->original_callback.Run(CACHE_STORAGE_ERROR_STORAGE,
+ std::vector<ServiceWorkerResponse>(),
+ ScopedVector<storage::BlobDataHandle>());
+ return;
+ }
+
+ // Create a blob with the response body data.
jkarlin 2015/08/05 12:09:05 The block of code below is duplicated from MatchDi
nhiroki 2015/08/06 03:36:53 Factored out the block into PopulateResponseBody()
+ response.blob_size = entry->GetDataSize(INDEX_RESPONSE_BODY);
+ response.blob_uuid = base::GenerateGUID();
+ storage::BlobDataBuilder blob_data(response.blob_uuid);
+
+ // Pass ownership of |entry| from the context to the handle.
+ disk_cache::Entry* entry_ptr = entry.get();
+ blob_data.AppendDiskCacheEntry(
+ new CacheStorageCacheDataHandle(this, entry.Pass()), entry_ptr,
+ INDEX_RESPONSE_BODY);
+ scoped_ptr<storage::BlobDataHandle> blob_data_handle(
+ blob_storage_context_->AddFinishedBlob(&blob_data));
+
+ context->out_responses.push_back(response);
+ context->out_blob_data_handles.push_back(blob_data_handle.release());
+ MatchAllProcessNextEntry(context.Pass(), iter + 1);
+}
+
void CacheStorageCache::Put(const CacheStorageBatchOperation& operation,
const ErrorCallback& callback) {
DCHECK(BACKEND_OPEN == backend_state_ || initializing_);
@@ -860,66 +1058,29 @@ void CacheStorageCache::KeysImpl(const RequestsCallback& callback) {
// The entries have to be loaded into a vector first because enumeration loops
// forever if you read data from a cache entry while enumerating.
- scoped_ptr<KeysContext> keys_context(new KeysContext(callback));
-
- keys_context->backend_iterator = backend_->CreateIterator();
- disk_cache::Backend::Iterator& iterator = *keys_context->backend_iterator;
- disk_cache::Entry** enumerated_entry = &keys_context->enumerated_entry;
-
- net::CompletionCallback open_entry_callback = base::Bind(
- &CacheStorageCache::KeysDidOpenNextEntry, weak_ptr_factory_.GetWeakPtr(),
- base::Passed(keys_context.Pass()));
-
- int rv = iterator.OpenNextEntry(enumerated_entry, open_entry_callback);
-
- if (rv != net::ERR_IO_PENDING)
- open_entry_callback.Run(rv);
+ OpenAllEntries(base::Bind(&CacheStorageCache::KeysDidOpenAllEntries,
+ weak_ptr_factory_.GetWeakPtr(), callback));
}
-void CacheStorageCache::KeysDidOpenNextEntry(
- scoped_ptr<KeysContext> keys_context,
- int rv) {
- if (rv == net::ERR_FAILED) {
- DCHECK(!keys_context->enumerated_entry);
- // Enumeration is complete, extract the requests from the entries.
- Entries::iterator iter = keys_context->entries.begin();
- KeysProcessNextEntry(keys_context.Pass(), iter);
- return;
- }
-
- if (rv < 0) {
- keys_context->original_callback.Run(CACHE_STORAGE_ERROR_STORAGE,
- scoped_ptr<Requests>());
- return;
- }
-
- if (backend_state_ != BACKEND_OPEN) {
- keys_context->original_callback.Run(CACHE_STORAGE_ERROR_NOT_FOUND,
- scoped_ptr<Requests>());
+void CacheStorageCache::KeysDidOpenAllEntries(
+ const RequestsCallback& callback,
+ scoped_ptr<OpenAllEntriesContext> entries_context,
+ CacheStorageError error) {
+ if (error != CACHE_STORAGE_OK) {
+ callback.Run(error, scoped_ptr<Requests>());
return;
}
- // Store the entry.
- keys_context->entries.push_back(keys_context->enumerated_entry);
- keys_context->enumerated_entry = NULL;
-
- // Enumerate the next entry.
- disk_cache::Backend::Iterator& iterator = *keys_context->backend_iterator;
- disk_cache::Entry** enumerated_entry = &keys_context->enumerated_entry;
- net::CompletionCallback open_entry_callback = base::Bind(
- &CacheStorageCache::KeysDidOpenNextEntry, weak_ptr_factory_.GetWeakPtr(),
- base::Passed(keys_context.Pass()));
-
- rv = iterator.OpenNextEntry(enumerated_entry, open_entry_callback);
-
- if (rv != net::ERR_IO_PENDING)
- open_entry_callback.Run(rv);
+ scoped_ptr<KeysContext> keys_context(new KeysContext(callback));
+ keys_context->entries_context.swap(entries_context);
+ Entries::iterator iter = keys_context->entries_context->entries.begin();
+ KeysProcessNextEntry(keys_context.Pass(), iter);
}
void CacheStorageCache::KeysProcessNextEntry(
scoped_ptr<KeysContext> keys_context,
const Entries::iterator& iter) {
- if (iter == keys_context->entries.end()) {
+ if (iter == keys_context->entries_context->entries.end()) {
// All done. Return all of the keys.
keys_context->original_callback.Run(CACHE_STORAGE_OK,
keys_context->out_keys.Pass());
@@ -1063,6 +1224,18 @@ void CacheStorageCache::PendingResponseCallback(
scheduler_->CompleteOperationAndRunNext();
}
+void CacheStorageCache::PendingResponsesCallback(
+ const ResponsesCallback& callback,
+ CacheStorageError error,
+ const std::vector<ServiceWorkerResponse>& responses,
+ ScopedVector<storage::BlobDataHandle> blob_data_handles) {
+ base::WeakPtr<CacheStorageCache> cache = weak_ptr_factory_.GetWeakPtr();
+
+ callback.Run(error, responses, blob_data_handles.Pass());
+ if (cache)
+ scheduler_->CompleteOperationAndRunNext();
+}
+
void CacheStorageCache::PendingRequestsCallback(
const RequestsCallback& callback,
CacheStorageError error,

Powered by Google App Engine
This is Rietveld 408576698