Commit 63cf86df authored by ericu@chromium.org's avatar ericu@chromium.org

The chromium-side backchannel plumbing for blobs in IDB.

This requires https://codereview.chromium.org/235933013/.

BUG=108012

Review URL: https://codereview.chromium.org/240003010

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@266677 0039d316-1c4b-4281-b951-d872f2087c98
parent c1c01db0
......@@ -520,33 +520,66 @@ void IndexedDBDispatcher::OnSuccessStringList(
pending_callbacks_.Remove(ipc_callbacks_id);
}
static void PrepareWebValueAndBlobInfo(
const std::string& value,
const std::vector<IndexedDBMsg_BlobOrFileInfo>& blob_info,
WebData* web_value,
blink::WebVector<WebBlobInfo>* web_blob_info) {
if (value.empty())
return;
web_value->assign(&*value.begin(), value.size());
blink::WebVector<WebBlobInfo> local_blob_info(blob_info.size());
for (size_t i = 0; i < blob_info.size(); ++i) {
const IndexedDBMsg_BlobOrFileInfo& info = blob_info[i];
if (info.is_file) {
local_blob_info[i] = WebBlobInfo(WebString::fromUTF8(info.uuid.c_str()),
info.file_path,
info.file_name,
info.mime_type,
info.last_modified,
info.size);
} else {
local_blob_info[i] = WebBlobInfo(
WebString::fromUTF8(info.uuid.c_str()), info.mime_type, info.size);
}
}
web_blob_info->swap(local_blob_info);
}
void IndexedDBDispatcher::OnSuccessValue(
const IndexedDBMsg_CallbacksSuccessValue_Params& p) {
DCHECK_EQ(p.ipc_thread_id, CurrentWorkerId());
WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(p.ipc_callbacks_id);
const IndexedDBMsg_CallbacksSuccessValue_Params& params) {
DCHECK_EQ(params.ipc_thread_id, CurrentWorkerId());
WebIDBCallbacks* callbacks =
pending_callbacks_.Lookup(params.ipc_callbacks_id);
if (!callbacks)
return;
WebData web_value;
if (!p.value.empty())
web_value.assign(&*p.value.begin(), p.value.size());
callbacks->onSuccess(web_value);
pending_callbacks_.Remove(p.ipc_callbacks_id);
cursor_transaction_ids_.erase(p.ipc_callbacks_id);
WebVector<WebBlobInfo> web_blob_info;
PrepareWebValueAndBlobInfo(
params.value, params.blob_or_file_info, &web_value, &web_blob_info);
callbacks->onSuccess(web_value, web_blob_info);
pending_callbacks_.Remove(params.ipc_callbacks_id);
cursor_transaction_ids_.erase(params.ipc_callbacks_id);
}
void IndexedDBDispatcher::OnSuccessValueWithKey(
const IndexedDBMsg_CallbacksSuccessValueWithKey_Params& p) {
DCHECK_EQ(p.ipc_thread_id, CurrentWorkerId());
WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(p.ipc_callbacks_id);
const IndexedDBMsg_CallbacksSuccessValueWithKey_Params& params) {
DCHECK_EQ(params.ipc_thread_id, CurrentWorkerId());
WebIDBCallbacks* callbacks =
pending_callbacks_.Lookup(params.ipc_callbacks_id);
if (!callbacks)
return;
WebData web_value;
if (p.value.size())
web_value.assign(&*p.value.begin(), p.value.size());
WebVector<WebBlobInfo> web_blob_info;
PrepareWebValueAndBlobInfo(
params.value, params.blob_or_file_info, &web_value, &web_blob_info);
callbacks->onSuccess(web_value,
WebIDBKeyBuilder::Build(p.primary_key),
WebIDBKeyPathBuilder::Build(p.key_path));
pending_callbacks_.Remove(p.ipc_callbacks_id);
web_blob_info,
WebIDBKeyBuilder::Build(params.primary_key),
WebIDBKeyPathBuilder::Build(params.key_path));
pending_callbacks_.Remove(params.ipc_callbacks_id);
}
void IndexedDBDispatcher::OnSuccessInteger(int32 ipc_thread_id,
......@@ -578,8 +611,9 @@ void IndexedDBDispatcher::OnSuccessOpenCursor(
const IndexedDBKey& key = p.key;
const IndexedDBKey& primary_key = p.primary_key;
WebData web_value;
if (p.value.size())
web_value.assign(&*p.value.begin(), p.value.size());
WebVector<WebBlobInfo> web_blob_info;
PrepareWebValueAndBlobInfo(
p.value, p.blob_or_file_info, &web_value, &web_blob_info);
DCHECK(cursor_transaction_ids_.find(ipc_callbacks_id) !=
cursor_transaction_ids_.end());
......@@ -593,8 +627,11 @@ void IndexedDBDispatcher::OnSuccessOpenCursor(
WebIDBCursorImpl* cursor = new WebIDBCursorImpl(
ipc_object_id, transaction_id, thread_safe_sender_.get());
cursors_[ipc_object_id] = cursor;
callbacks->onSuccess(cursor, WebIDBKeyBuilder::Build(key),
WebIDBKeyBuilder::Build(primary_key), web_value);
callbacks->onSuccess(cursor,
WebIDBKeyBuilder::Build(key),
WebIDBKeyBuilder::Build(primary_key),
web_value,
web_blob_info);
pending_callbacks_.Remove(ipc_callbacks_id);
}
......@@ -616,10 +653,13 @@ void IndexedDBDispatcher::OnSuccessCursorContinue(
return;
WebData web_value;
if (value.size())
web_value.assign(&*value.begin(), value.size());
WebVector<WebBlobInfo> web_blob_info;
PrepareWebValueAndBlobInfo(
value, p.blob_or_file_info, &web_value, &web_blob_info);
callbacks->onSuccess(WebIDBKeyBuilder::Build(key),
WebIDBKeyBuilder::Build(primary_key), web_value);
WebIDBKeyBuilder::Build(primary_key),
web_value,
web_blob_info);
pending_callbacks_.Remove(ipc_callbacks_id);
}
......@@ -632,13 +672,15 @@ void IndexedDBDispatcher::OnSuccessCursorPrefetch(
const std::vector<IndexedDBKey>& keys = p.keys;
const std::vector<IndexedDBKey>& primary_keys = p.primary_keys;
std::vector<WebData> values(p.values.size());
DCHECK_EQ(p.values.size(), p.blob_or_file_infos.size());
std::vector<WebVector<WebBlobInfo> > blob_infos(p.blob_or_file_infos.size());
for (size_t i = 0; i < p.values.size(); ++i) {
if (p.values[i].size())
values[i].assign(&*p.values[i].begin(), p.values[i].size());
PrepareWebValueAndBlobInfo(
p.values[i], p.blob_or_file_infos[i], &values[i], &blob_infos[i]);
}
WebIDBCursorImpl* cursor = cursors_[ipc_cursor_id];
DCHECK(cursor);
cursor->SetPrefetchData(keys, primary_keys, values);
cursor->SetPrefetchData(keys, primary_keys, values, blob_infos);
WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(ipc_callbacks_id);
DCHECK(callbacks);
......
......@@ -137,8 +137,7 @@ class CONTENT_EXPORT IndexedDBDispatcher : public WorkerTaskRunner::Observer {
blink::WebIDBDatabase::PutMode put_mode,
blink::WebIDBCallbacks* callbacks,
const blink::WebVector<long long>& index_ids,
const blink::WebVector<blink::WebVector<blink::WebIDBKey> >&
index_keys);
const blink::WebVector<blink::WebVector<blink::WebIDBKey> >& index_keys);
void RequestIDBDatabaseOpenCursor(int32 ipc_database_id,
int64 transaction_id,
......
......@@ -130,11 +130,13 @@ class CursorCallbacks : public WebIDBCallbacks {
public:
CursorCallbacks(scoped_ptr<WebIDBCursor>* cursor) : cursor_(cursor) {}
virtual void onSuccess(const WebData&) OVERRIDE {}
virtual void onSuccess(const WebData&,
const WebVector<WebBlobInfo>&) OVERRIDE {}
virtual void onSuccess(WebIDBCursor* cursor,
const WebIDBKey& key,
const WebIDBKey& primaryKey,
const WebData& value) OVERRIDE {
const WebData& value,
const WebVector<WebBlobInfo>&) OVERRIDE {
cursor_->reset(cursor);
}
......
......@@ -122,10 +122,12 @@ void WebIDBCursorImpl::postSuccessHandlerCallback() {
void WebIDBCursorImpl::SetPrefetchData(
const std::vector<IndexedDBKey>& keys,
const std::vector<IndexedDBKey>& primary_keys,
const std::vector<WebData>& values) {
const std::vector<WebData>& values,
const std::vector<blink::WebVector<blink::WebBlobInfo> >& blob_info) {
prefetch_keys_.assign(keys.begin(), keys.end());
prefetch_primary_keys_.assign(primary_keys.begin(), primary_keys.end());
prefetch_values_.assign(values.begin(), values.end());
prefetch_blob_info_.assign(blob_info.begin(), blob_info.end());
used_prefetches_ = 0;
pending_onsuccess_callbacks_ = 0;
......@@ -136,11 +138,13 @@ void WebIDBCursorImpl::CachedAdvance(unsigned long count,
DCHECK_GE(prefetch_keys_.size(), count);
DCHECK_EQ(prefetch_primary_keys_.size(), prefetch_keys_.size());
DCHECK_EQ(prefetch_values_.size(), prefetch_keys_.size());
DCHECK_EQ(prefetch_blob_info_.size(), prefetch_keys_.size());
while (count > 1) {
prefetch_keys_.pop_front();
prefetch_primary_keys_.pop_front();
prefetch_values_.pop_front();
prefetch_blob_info_.pop_front();
++used_prefetches_;
--count;
}
......@@ -152,14 +156,17 @@ void WebIDBCursorImpl::CachedContinue(WebIDBCallbacks* callbacks) {
DCHECK_GT(prefetch_keys_.size(), 0ul);
DCHECK_EQ(prefetch_primary_keys_.size(), prefetch_keys_.size());
DCHECK_EQ(prefetch_values_.size(), prefetch_keys_.size());
DCHECK_EQ(prefetch_blob_info_.size(), prefetch_keys_.size());
IndexedDBKey key = prefetch_keys_.front();
IndexedDBKey primary_key = prefetch_primary_keys_.front();
WebData value = prefetch_values_.front();
blink::WebVector<blink::WebBlobInfo> blob_info = prefetch_blob_info_.front();
prefetch_keys_.pop_front();
prefetch_primary_keys_.pop_front();
prefetch_values_.pop_front();
prefetch_blob_info_.pop_front();
++used_prefetches_;
++pending_onsuccess_callbacks_;
......@@ -174,7 +181,8 @@ void WebIDBCursorImpl::CachedContinue(WebIDBCallbacks* callbacks) {
callbacks->onSuccess(WebIDBKeyBuilder::Build(key),
WebIDBKeyBuilder::Build(primary_key),
value);
value,
blob_info);
}
void WebIDBCursorImpl::ResetPrefetchCache() {
......@@ -193,6 +201,7 @@ void WebIDBCursorImpl::ResetPrefetchCache() {
prefetch_keys_.clear();
prefetch_primary_keys_.clear();
prefetch_values_.clear();
prefetch_blob_info_.clear();
pending_onsuccess_callbacks_ = 0;
}
......
......@@ -38,9 +38,11 @@ class CONTENT_EXPORT WebIDBCursorImpl
blink::WebIDBCallbacks* callback);
virtual void postSuccessHandlerCallback();
void SetPrefetchData(const std::vector<IndexedDBKey>& keys,
const std::vector<IndexedDBKey>& primary_keys,
const std::vector<blink::WebData>& values);
void SetPrefetchData(
const std::vector<IndexedDBKey>& keys,
const std::vector<IndexedDBKey>& primary_keys,
const std::vector<blink::WebData>& values,
const std::vector<blink::WebVector<blink::WebBlobInfo> >& blob_info);
void CachedAdvance(unsigned long count, blink::WebIDBCallbacks* callbacks);
void CachedContinue(blink::WebIDBCallbacks* callbacks);
......@@ -64,6 +66,7 @@ class CONTENT_EXPORT WebIDBCursorImpl
std::deque<IndexedDBKey> prefetch_keys_;
std::deque<IndexedDBKey> prefetch_primary_keys_;
std::deque<blink::WebData> prefetch_values_;
std::deque<blink::WebVector<blink::WebBlobInfo> > prefetch_blob_info_;
// Number of continue calls that would qualify for a pre-fetch.
int continue_count_;
......
......@@ -14,11 +14,13 @@
#include "third_party/WebKit/public/platform/WebData.h"
#include "third_party/WebKit/public/platform/WebIDBCallbacks.h"
using blink::WebBlobInfo;
using blink::WebData;
using blink::WebIDBCallbacks;
using blink::WebIDBDatabase;
using blink::WebIDBKey;
using blink::WebIDBKeyTypeNumber;
using blink::WebVector;
namespace content {
......@@ -93,18 +95,24 @@ class MockDispatcher : public IndexedDBDispatcher {
class MockContinueCallbacks : public WebIDBCallbacks {
public:
MockContinueCallbacks(IndexedDBKey* key = 0) : key_(key) {}
MockContinueCallbacks(IndexedDBKey* key = 0,
WebVector<WebBlobInfo>* webBlobInfo = 0)
: key_(key), webBlobInfo_(webBlobInfo) {}
virtual void onSuccess(const WebIDBKey& key,
const WebIDBKey& primaryKey,
const WebData& value) {
const WebData& value,
const WebVector<WebBlobInfo>& webBlobInfo) OVERRIDE {
if (key_)
*key_ = IndexedDBKeyBuilder::Build(key);
if (webBlobInfo_)
*webBlobInfo_ = webBlobInfo;
}
private:
IndexedDBKey* key_;
WebVector<WebBlobInfo>* webBlobInfo_;
};
} // namespace
......@@ -171,10 +179,13 @@ TEST_F(WebIDBCursorImplTest, PrefetchTest) {
std::vector<IndexedDBKey> keys;
std::vector<IndexedDBKey> primary_keys(prefetch_count);
std::vector<WebData> values(prefetch_count);
std::vector<WebVector<WebBlobInfo> > blob_info;
for (int i = 0; i < prefetch_count; ++i) {
keys.push_back(IndexedDBKey(expected_key + i, WebIDBKeyTypeNumber));
blob_info.push_back(
WebVector<WebBlobInfo>(static_cast<size_t>(expected_key + i)));
}
cursor.SetPrefetchData(keys, primary_keys, values);
cursor.SetPrefetchData(keys, primary_keys, values, blob_info);
// Note that the real dispatcher would call cursor->CachedContinue()
// immediately after cursor->SetPrefetchData() to service the request
......@@ -183,11 +194,14 @@ TEST_F(WebIDBCursorImplTest, PrefetchTest) {
// Verify that the cache is used for subsequent continue() calls.
for (int i = 0; i < prefetch_count; ++i) {
IndexedDBKey key;
cursor.continueFunction(null_key_, new MockContinueCallbacks(&key));
WebVector<WebBlobInfo> web_blob_info;
cursor.continueFunction(
null_key_, new MockContinueCallbacks(&key, &web_blob_info));
EXPECT_EQ(continue_calls, dispatcher_->continue_calls());
EXPECT_EQ(repetitions + 1, dispatcher_->prefetch_calls());
EXPECT_EQ(WebIDBKeyTypeNumber, key.type());
EXPECT_EQ(expected_key, static_cast<int>(web_blob_info.size()));
EXPECT_EQ(expected_key++, key.number());
}
}
......@@ -226,10 +240,13 @@ TEST_F(WebIDBCursorImplTest, AdvancePrefetchTest) {
std::vector<IndexedDBKey> keys;
std::vector<IndexedDBKey> primary_keys(prefetch_count);
std::vector<WebData> values(prefetch_count);
std::vector<WebVector<WebBlobInfo> > blob_info;
for (int i = 0; i < prefetch_count; ++i) {
keys.push_back(IndexedDBKey(expected_key + i, WebIDBKeyTypeNumber));
blob_info.push_back(
WebVector<WebBlobInfo>(static_cast<size_t>(expected_key + i)));
}
cursor.SetPrefetchData(keys, primary_keys, values);
cursor.SetPrefetchData(keys, primary_keys, values, blob_info);
// Note that the real dispatcher would call cursor->CachedContinue()
// immediately after cursor->SetPrefetchData() to service the request
......@@ -298,7 +315,8 @@ TEST_F(WebIDBCursorImplTest, PrefetchReset) {
std::vector<IndexedDBKey> keys(prefetch_count);
std::vector<IndexedDBKey> primary_keys(prefetch_count);
std::vector<WebData> values(prefetch_count);
cursor.SetPrefetchData(keys, primary_keys, values);
std::vector<WebVector<WebBlobInfo> > blob_info(prefetch_count);
cursor.SetPrefetchData(keys, primary_keys, values, blob_info);
// No reset should have been sent since prefetch data hasn't been used.
EXPECT_EQ(0, dispatcher_->reset_calls());
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment