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

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: replace ScopedVector<BlobDataHandle> with scoped_ptr<std::vector<BlobDataHandle>> 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 cf98e5007e766edb459f3638331454e433be7520..dcc9c3d0da7d3ac00b00b734ac7636d3e6dd5bc7 100644
--- a/content/browser/cache_storage/cache_storage_cache.cc
+++ b/content/browser/cache_storage/cache_storage_cache.cc
@@ -182,34 +182,67 @@ void ReadMetadataDidReadMetadata(
} // namespace
-// 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();
+// 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)
enumerated_entry->Close();
}
- // 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;
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),
+ out_responses(new Responses),
+ out_blob_data_handles(new BlobDataHandles) {}
+ ~MatchAllContext() {}
+
+ // The callback passed to the MatchAll() function.
+ ResponsesCallback original_callback;
+
+ // The outputs of the MatchAll function.
+ scoped_ptr<Responses> out_responses;
+ scoped_ptr<BlobDataHandles> 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 Requests()) {}
+ ~KeysContext() {}
+
+ // The callback passed to the Keys() function.
+ RequestsCallback original_callback;
+
+ // The output of the Keys function.
+ scoped_ptr<Requests> out_keys;
+
+ // The context holding open entries.
+ scoped_ptr<OpenAllEntriesContext> entries_context;
+
+ private:
DISALLOW_COPY_AND_ASSIGN(KeysContext);
};
@@ -291,6 +324,21 @@ 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, scoped_ptr<Responses>(),
+ scoped_ptr<BlobDataHandles>());
+ 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) {
@@ -436,6 +484,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_);
@@ -493,22 +595,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);
+ PopulateResponseMetadata(*metadata, response.get());
ServiceWorkerHeaderMap cached_request_headers;
for (int i = 0; i < metadata->request().headers_size(); ++i) {
@@ -539,20 +627,92 @@ void CacheStorageCache::MatchDidReadMetadata(
return;
}
- // Create a blob with the response body data.
- response->blob_size = entry->GetDataSize(INDEX_RESPONSE_BODY);
- response->blob_uuid = base::GenerateGUID();
- storage::BlobDataBuilder blob_data(response->blob_uuid);
-
- disk_cache::Entry* temp_entry = entry.get();
- blob_data.AppendDiskCacheEntry(
- new CacheStorageCacheDataHandle(this, entry.Pass()), temp_entry,
- INDEX_RESPONSE_BODY);
- scoped_ptr<storage::BlobDataHandle> blob_data_handle(
- blob_storage_context_->AddFinishedBlob(&blob_data));
+ scoped_ptr<storage::BlobDataHandle> blob_data_handle =
+ PopulateResponseBody(entry.Pass(), response.get());
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, scoped_ptr<Responses>(),
+ scoped_ptr<BlobDataHandles>());
+ 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, scoped_ptr<Responses>(), scoped_ptr<BlobDataHandles>());
+ 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.Pass(),
+ 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;
+ PopulateResponseMetadata(*metadata, &response);
+
+ if (entry->GetDataSize(INDEX_RESPONSE_BODY) == 0) {
+ context->out_responses->push_back(response);
+ MatchAllProcessNextEntry(context.Pass(), iter + 1);
+ return;
+ }
+
+ if (!blob_storage_context_) {
+ context->original_callback.Run(CACHE_STORAGE_ERROR_STORAGE,
+ scoped_ptr<Responses>(),
+ scoped_ptr<BlobDataHandles>());
+ return;
+ }
+
+ scoped_ptr<storage::BlobDataHandle> blob_data_handle =
+ PopulateResponseBody(entry.Pass(), &response);
+
+ context->out_responses->push_back(response);
+ context->out_blob_data_handles->push_back(*blob_data_handle);
+ MatchAllProcessNextEntry(context.Pass(), iter + 1);
+}
+
void CacheStorageCache::Put(const CacheStorageBatchOperation& operation,
const ErrorCallback& callback) {
DCHECK(BACKEND_OPEN == backend_state_ || initializing_);
@@ -864,66 +1024,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());
@@ -1067,6 +1190,18 @@ void CacheStorageCache::PendingResponseCallback(
scheduler_->CompleteOperationAndRunNext();
}
+void CacheStorageCache::PendingResponsesCallback(
+ const ResponsesCallback& callback,
+ CacheStorageError error,
+ scoped_ptr<Responses> responses,
+ scoped_ptr<BlobDataHandles> blob_data_handles) {
+ base::WeakPtr<CacheStorageCache> cache = weak_ptr_factory_.GetWeakPtr();
+
+ callback.Run(error, responses.Pass(), blob_data_handles.Pass());
+ if (cache)
+ scheduler_->CompleteOperationAndRunNext();
+}
+
void CacheStorageCache::PendingRequestsCallback(
const RequestsCallback& callback,
CacheStorageError error,
@@ -1078,4 +1213,39 @@ void CacheStorageCache::PendingRequestsCallback(
scheduler_->CompleteOperationAndRunNext();
}
+void CacheStorageCache::PopulateResponseMetadata(
+ const CacheMetadata& metadata,
+ 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()));
+ }
+}
+
+scoped_ptr<storage::BlobDataHandle> CacheStorageCache::PopulateResponseBody(
+ disk_cache::ScopedEntryPtr entry,
+ ServiceWorkerResponse* response) {
+ DCHECK(blob_storage_context_);
+
+ // Create a blob with the response body data.
+ response->blob_size = entry->GetDataSize(INDEX_RESPONSE_BODY);
+ response->blob_uuid = base::GenerateGUID();
+ storage::BlobDataBuilder blob_data(response->blob_uuid);
+
+ disk_cache::Entry* temp_entry = entry.get();
+ blob_data.AppendDiskCacheEntry(
+ new CacheStorageCacheDataHandle(this, entry.Pass()), temp_entry,
+ INDEX_RESPONSE_BODY);
+ return blob_storage_context_->AddFinishedBlob(&blob_data);
+}
+
} // namespace content
« no previous file with comments | « content/browser/cache_storage/cache_storage_cache.h ('k') | content/browser/cache_storage/cache_storage_cache_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698