Commit 77931ff3 authored by hans@chromium.org's avatar hans@chromium.org

IndexedDB: Cursor pre-fetching.

Add support for cursor pre-fetching.

BUG=88651
TEST=browser_tests

Review URL: http://codereview.chromium.org/8662017

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@112675 0039d316-1c4b-4281-b951-d872f2087c98
parent 5c6b568c
......@@ -4,7 +4,10 @@
function debug(message)
{
document.getElementById('status').innerHTML += '<br/>' + message;
var span = document.createElement("span");
span.appendChild(document.createTextNode(message));
span.appendChild(document.createElement("br"));
document.getElementById('status').appendChild(span);
}
function done(message)
......
<html>
<head>
<title>IndexedDB cursor prefetch test</title>
<script type="text/javascript" src="common.js"></script>
<script type="text/javascript" src="cursor_prefetch.js"></script>
</head>
<body onLoad="test()">
<div id="status">Starting...</div>
</body>
</html>
This diff is collapsed.
......@@ -69,6 +69,10 @@ IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, CursorTestIncognito) {
true /* incognito */);
}
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, CursorPrefetch) {
SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("cursor_prefetch.html"))));
}
// Flaky: http://crbug.com/70773
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, DISABLED_IndexTest) {
SimpleTest(testUrl(FilePath(FILE_PATH_LITERAL("index_test.html"))));
......
......@@ -59,6 +59,31 @@ void IndexedDBCallbacks<WebKit::WebIDBCursor>::onSuccessWithContinuation() {
content::SerializedScriptValue(idb_cursor->value())));
}
void IndexedDBCallbacks<WebKit::WebIDBCursor>::onSuccessWithPrefetch(
const WebKit::WebVector<WebKit::WebIDBKey>& keys,
const WebKit::WebVector<WebKit::WebIDBKey>& primaryKeys,
const WebKit::WebVector<WebKit::WebSerializedScriptValue>& values) {
DCHECK(cursor_id_ != -1);
std::vector<IndexedDBKey> msgKeys;
std::vector<IndexedDBKey> msgPrimaryKeys;
std::vector<content::SerializedScriptValue> msgValues;
for (size_t i = 0; i < keys.size(); ++i) {
msgKeys.push_back(IndexedDBKey(keys[i]));
msgPrimaryKeys.push_back(IndexedDBKey(primaryKeys[i]));
msgValues.push_back(content::SerializedScriptValue(values[i]));
}
dispatcher_host()->Send(
new IndexedDBMsg_CallbacksSuccessCursorPrefetch(
response_id(),
cursor_id_,
msgKeys,
msgPrimaryKeys,
msgValues));
}
void IndexedDBCallbacks<WebKit::WebIDBKey>::onSuccess(
const WebKit::WebIDBKey& value) {
dispatcher_host()->Send(
......
......@@ -93,6 +93,10 @@ class IndexedDBCallbacks<WebKit::WebIDBCursor>
virtual void onSuccess(WebKit::WebIDBCursor* idb_object);
virtual void onSuccess(const WebKit::WebSerializedScriptValue& value);
virtual void onSuccessWithContinuation();
virtual void onSuccessWithPrefetch(
const WebKit::WebVector<WebKit::WebIDBKey>& keys,
const WebKit::WebVector<WebKit::WebIDBKey>& primaryKeys,
const WebKit::WebVector<WebKit::WebSerializedScriptValue>& values);
private:
// The id of the cursor this callback concerns, or -1 if the cursor
......
......@@ -886,6 +886,8 @@ bool IndexedDBDispatcherHost::CursorDispatcherHost::OnMessageReceived(
IPC_MESSAGE_HANDLER(IndexedDBHostMsg_CursorDirection, OnDirection)
IPC_MESSAGE_HANDLER(IndexedDBHostMsg_CursorUpdate, OnUpdate)
IPC_MESSAGE_HANDLER(IndexedDBHostMsg_CursorContinue, OnContinue)
IPC_MESSAGE_HANDLER(IndexedDBHostMsg_CursorPrefetch, OnPrefetch)
IPC_MESSAGE_HANDLER(IndexedDBHostMsg_CursorPrefetchReset, OnPrefetchReset)
IPC_MESSAGE_HANDLER(IndexedDBHostMsg_CursorDelete, OnDelete)
IPC_MESSAGE_HANDLER(IndexedDBHostMsg_CursorDestroyed, OnDestroyed)
IPC_MESSAGE_UNHANDLED(handled = false)
......@@ -967,6 +969,32 @@ void IndexedDBDispatcherHost::CursorDispatcherHost::OnContinue(
cursor_id), *ec);
}
void IndexedDBDispatcherHost::CursorDispatcherHost::OnPrefetch(
int32 cursor_id,
int32 response_id,
int n,
WebKit::WebExceptionCode* ec) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
WebIDBCursor* idb_cursor = parent_->GetOrTerminateProcess(&map_, cursor_id);
if (!idb_cursor)
return;
*ec = 0;
idb_cursor->prefetchContinue(
n, new IndexedDBCallbacks<WebIDBCursor>(parent_, response_id,
cursor_id), *ec);
}
void IndexedDBDispatcherHost::CursorDispatcherHost::OnPrefetchReset(
int32 cursor_id, int used_prefetches, int unused_prefetches) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
WebIDBCursor* idb_cursor = parent_->GetOrTerminateProcess(&map_, cursor_id);
if (!idb_cursor)
return;
idb_cursor->prefetchReset(used_prefetches, unused_prefetches);
}
void IndexedDBDispatcherHost::CursorDispatcherHost::OnDelete(
int32 cursor_id,
int32 response_id,
......
......@@ -238,6 +238,12 @@ class IndexedDBDispatcherHost : public BrowserMessageFilter {
int32 response_id,
const IndexedDBKey& key,
WebKit::WebExceptionCode* ec);
void OnPrefetch(int32 idb_cursor_id,
int32 response_id,
int n,
WebKit::WebExceptionCode* ec);
void OnPrefetchReset(int32 idb_cursor_id, int used_prefetches,
int unused_prefetches);
void OnDelete(int32 idb_object_store_id,
int32 response_id,
WebKit::WebExceptionCode* ec);
......
......@@ -147,6 +147,12 @@ IPC_MESSAGE_CONTROL5(IndexedDBMsg_CallbacksSuccessCursorContinue,
IndexedDBKey /* key */,
IndexedDBKey /* primary key */,
content::SerializedScriptValue /* script_value */)
IPC_MESSAGE_CONTROL5(IndexedDBMsg_CallbacksSuccessCursorPrefetch,
int32 /* response_id */,
int32 /* cursor_id */,
std::vector<IndexedDBKey> /* keys */,
std::vector<IndexedDBKey> /* primary keys */,
std::vector<content::SerializedScriptValue> /* values */)
IPC_MESSAGE_CONTROL2(IndexedDBMsg_CallbacksSuccessIDBDatabase,
int32 /* response_id */,
int32 /* idb_database_id */)
......@@ -200,6 +206,19 @@ IPC_SYNC_MESSAGE_CONTROL3_1(IndexedDBHostMsg_CursorContinue,
IndexedDBKey, /* key */
WebKit::WebExceptionCode /* ec */)
// WebIDBCursor::prefetchContinue() message.
IPC_SYNC_MESSAGE_CONTROL3_1(IndexedDBHostMsg_CursorPrefetch,
int32, /* idb_cursor_id */
int32, /* response_id */
int32, /* n */
WebKit::WebExceptionCode /* ec */)
// WebIDBCursor::prefetchReset() message.
IPC_SYNC_MESSAGE_CONTROL3_0(IndexedDBHostMsg_CursorPrefetchReset,
int32, /* idb_cursor_id */
int32, /* used_prefetches */
int32 /* used_prefetches */)
// WebIDBCursor::remove() message.
IPC_SYNC_MESSAGE_CONTROL2_1(IndexedDBHostMsg_CursorDelete,
int32, /* idb_cursor_id */
......
......@@ -44,6 +44,8 @@ bool IndexedDBDispatcher::OnMessageReceived(const IPC::Message& msg) {
OnSuccessOpenCursor)
IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessCursorContinue,
OnSuccessCursorContinue)
IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessCursorPrefetch,
OnSuccessCursorPrefetch)
IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessIDBDatabase,
OnSuccessIDBDatabase)
IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessIndexedDBKey,
......@@ -74,6 +76,7 @@ void IndexedDBDispatcher::RequestIDBCursorUpdate(
WebIDBCallbacks* callbacks_ptr,
int32 idb_cursor_id,
WebExceptionCode* ec) {
ResetCursorPrefetchCaches();
scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
int32 response_id = pending_callbacks_.Add(callbacks.release());
......@@ -88,6 +91,9 @@ void IndexedDBDispatcher::RequestIDBCursorContinue(
WebIDBCallbacks* callbacks_ptr,
int32 idb_cursor_id,
WebExceptionCode* ec) {
// Reset all cursor prefetch caches except for this cursor.
ResetCursorPrefetchCaches(idb_cursor_id);
scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
int32 response_id = pending_callbacks_.Add(callbacks.release());
......@@ -97,10 +103,32 @@ void IndexedDBDispatcher::RequestIDBCursorContinue(
pending_callbacks_.Remove(response_id);
}
void IndexedDBDispatcher::RequestIDBCursorPrefetch(
int n,
WebIDBCallbacks* callbacks_ptr,
int32 idb_cursor_id,
WebExceptionCode* ec) {
scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
int32 response_id = pending_callbacks_.Add(callbacks.release());
RenderThreadImpl::current()->Send(
new IndexedDBHostMsg_CursorPrefetch(idb_cursor_id, response_id, n, ec));
if (*ec)
pending_callbacks_.Remove(response_id);
}
void IndexedDBDispatcher::RequestIDBCursorPrefetchReset(
int used_prefetches, int unused_prefetches, int32 idb_cursor_id) {
RenderThreadImpl::current()->Send(
new IndexedDBHostMsg_CursorPrefetchReset(idb_cursor_id, used_prefetches,
unused_prefetches));
}
void IndexedDBDispatcher::RequestIDBCursorDelete(
WebIDBCallbacks* callbacks_ptr,
int32 idb_cursor_id,
WebExceptionCode* ec) {
ResetCursorPrefetchCaches();
scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
int32 response_id = pending_callbacks_.Add(callbacks.release());
......@@ -114,6 +142,7 @@ void IndexedDBDispatcher::RequestIDBFactoryOpen(
WebIDBCallbacks* callbacks_ptr,
const string16& origin,
WebFrame* web_frame) {
ResetCursorPrefetchCaches();
scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
if (!web_frame)
......@@ -133,6 +162,7 @@ void IndexedDBDispatcher::RequestIDBFactoryGetDatabaseNames(
WebIDBCallbacks* callbacks_ptr,
const string16& origin,
WebFrame* web_frame) {
ResetCursorPrefetchCaches();
scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
if (!web_frame)
......@@ -152,6 +182,7 @@ void IndexedDBDispatcher::RequestIDBFactoryDeleteDatabase(
WebIDBCallbacks* callbacks_ptr,
const string16& origin,
WebFrame* web_frame) {
ResetCursorPrefetchCaches();
scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
if (!web_frame)
......@@ -168,6 +199,7 @@ void IndexedDBDispatcher::RequestIDBFactoryDeleteDatabase(
}
void IndexedDBDispatcher::RequestIDBDatabaseClose(int32 idb_database_id) {
ResetCursorPrefetchCaches();
Send(new IndexedDBHostMsg_DatabaseClose(idb_database_id));
pending_database_callbacks_.Remove(idb_database_id);
}
......@@ -175,6 +207,7 @@ void IndexedDBDispatcher::RequestIDBDatabaseClose(int32 idb_database_id) {
void IndexedDBDispatcher::RequestIDBDatabaseOpen(
WebIDBDatabaseCallbacks* callbacks_ptr,
int32 idb_database_id) {
ResetCursorPrefetchCaches();
scoped_ptr<WebIDBDatabaseCallbacks> callbacks(callbacks_ptr);
int32 response_id = pending_database_callbacks_.Add(callbacks.release());
......@@ -186,6 +219,7 @@ void IndexedDBDispatcher::RequestIDBDatabaseSetVersion(
WebIDBCallbacks* callbacks_ptr,
int32 idb_database_id,
WebExceptionCode* ec) {
ResetCursorPrefetchCaches();
scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
int32 response_id = pending_callbacks_.Add(callbacks.release());
......@@ -202,6 +236,7 @@ void IndexedDBDispatcher::RequestIDBIndexOpenObjectCursor(
int32 idb_index_id,
const WebIDBTransaction& transaction,
WebExceptionCode* ec) {
ResetCursorPrefetchCaches();
scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
IndexedDBHostMsg_IndexOpenCursor_Params params;
params.response_id = pending_callbacks_.Add(callbacks.release());
......@@ -224,6 +259,7 @@ void IndexedDBDispatcher::RequestIDBIndexOpenKeyCursor(
int32 idb_index_id,
const WebIDBTransaction& transaction,
WebExceptionCode* ec) {
ResetCursorPrefetchCaches();
scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
IndexedDBHostMsg_IndexOpenCursor_Params params;
params.response_id = pending_callbacks_.Add(callbacks.release());
......@@ -247,6 +283,7 @@ void IndexedDBDispatcher::RequestIDBIndexGetObject(
int32 idb_index_id,
const WebIDBTransaction& transaction,
WebExceptionCode* ec) {
ResetCursorPrefetchCaches();
scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
int32 response_id = pending_callbacks_.Add(callbacks.release());
Send(new IndexedDBHostMsg_IndexGetObject(idb_index_id, response_id, key,
......@@ -261,6 +298,7 @@ void IndexedDBDispatcher::RequestIDBIndexGetKey(
int32 idb_index_id,
const WebIDBTransaction& transaction,
WebExceptionCode* ec) {
ResetCursorPrefetchCaches();
scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
int32 response_id = pending_callbacks_.Add(callbacks.release());
Send(new IndexedDBHostMsg_IndexGetKey(
......@@ -276,6 +314,7 @@ void IndexedDBDispatcher::RequestIDBObjectStoreGet(
int32 idb_object_store_id,
const WebIDBTransaction& transaction,
WebExceptionCode* ec) {
ResetCursorPrefetchCaches();
scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
int32 response_id = pending_callbacks_.Add(callbacks.release());
......@@ -294,6 +333,7 @@ void IndexedDBDispatcher::RequestIDBObjectStorePut(
int32 idb_object_store_id,
const WebIDBTransaction& transaction,
WebExceptionCode* ec) {
ResetCursorPrefetchCaches();
scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
IndexedDBHostMsg_ObjectStorePut_Params params;
params.idb_object_store_id = idb_object_store_id;
......@@ -313,6 +353,7 @@ void IndexedDBDispatcher::RequestIDBObjectStoreDelete(
int32 idb_object_store_id,
const WebIDBTransaction& transaction,
WebExceptionCode* ec) {
ResetCursorPrefetchCaches();
scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
int32 response_id = pending_callbacks_.Add(callbacks.release());
......@@ -327,6 +368,7 @@ void IndexedDBDispatcher::RequestIDBObjectStoreClear(
int32 idb_object_store_id,
const WebIDBTransaction& transaction,
WebExceptionCode* ec) {
ResetCursorPrefetchCaches();
scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
int32 response_id = pending_callbacks_.Add(callbacks.release());
......@@ -343,6 +385,7 @@ void IndexedDBDispatcher::RequestIDBObjectStoreOpenCursor(
int32 idb_object_store_id,
const WebIDBTransaction& transaction,
WebExceptionCode* ec) {
ResetCursorPrefetchCaches();
scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr);
IndexedDBHostMsg_ObjectStoreOpenCursor_Params params;
params.response_id = pending_callbacks_.Add(callbacks.release());
......@@ -458,6 +501,21 @@ void IndexedDBDispatcher::OnSuccessCursorContinue(
pending_callbacks_.Remove(response_id);
}
void IndexedDBDispatcher::OnSuccessCursorPrefetch(
int32 response_id,
int32 cursor_id,
const std::vector<IndexedDBKey>& keys,
const std::vector<IndexedDBKey>& primary_keys,
const std::vector<content::SerializedScriptValue>& values) {
RendererWebIDBCursorImpl* cursor = cursors_[cursor_id];
DCHECK(cursor);
cursor->SetPrefetchData(keys, primary_keys, values);
WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(response_id);
cursor->CachedContinue(callbacks);
pending_callbacks_.Remove(response_id);
}
void IndexedDBDispatcher::OnBlocked(int32 response_id) {
WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(response_id);
callbacks->onBlocked();
......@@ -500,3 +558,12 @@ void IndexedDBDispatcher::OnVersionChange(int32 database_id,
return;
callbacks->onVersionChange(newVersion);
}
void IndexedDBDispatcher::ResetCursorPrefetchCaches(int32 exception_cursor_id) {
typedef std::map<int32, RendererWebIDBCursorImpl*>::iterator Iterator;
for (Iterator i = cursors_.begin(); i != cursors_.end(); ++i) {
if (i->first == exception_cursor_id)
continue;
i->second->ResetPrefetchCache();
}
}
......@@ -70,6 +70,15 @@ class IndexedDBDispatcher : public IPC::Channel::Listener {
int32 idb_cursor_id,
WebKit::WebExceptionCode* ec);
void RequestIDBCursorPrefetch(
int n,
WebKit::WebIDBCallbacks* callbacks_ptr,
int32 idb_cursor_id,
WebKit::WebExceptionCode* ec);
void RequestIDBCursorPrefetchReset(int used_prefetches, int unused_prefetches,
int32 idb_cursor_id);
void RequestIDBCursorDelete(
WebKit::WebIDBCallbacks* callbacks_ptr,
int32 idb_cursor_id,
......@@ -174,6 +183,12 @@ class IndexedDBDispatcher : public IPC::Channel::Listener {
const IndexedDBKey& key,
const IndexedDBKey& primary_key,
const content::SerializedScriptValue& value);
void OnSuccessCursorPrefetch(
int32 response_id,
int32 cursor_id,
const std::vector<IndexedDBKey>& keys,
const std::vector<IndexedDBKey>& primary_keys,
const std::vector<content::SerializedScriptValue>& values);
void OnSuccessStringList(int32 response_id,
const std::vector<string16>& value);
void OnSuccessSerializedScriptValue(
......@@ -185,6 +200,9 @@ class IndexedDBDispatcher : public IPC::Channel::Listener {
void OnComplete(int32 transaction_id);
void OnVersionChange(int32 database_id, const string16& newVersion);
// Reset cursor prefetch caches for all cursors except exception_cursor_id.
void ResetCursorPrefetchCaches(int32 exception_cursor_id = -1);
// Careful! WebIDBCallbacks wraps non-threadsafe data types. It must be
// destroyed and used on the same thread it was created on.
IDMap<WebKit::WebIDBCallbacks, IDMapOwnPointer> pending_callbacks_;
......
......@@ -14,7 +14,11 @@ using WebKit::WebIDBKey;
using WebKit::WebSerializedScriptValue;
RendererWebIDBCursorImpl::RendererWebIDBCursorImpl(int32 idb_cursor_id)
: idb_cursor_id_(idb_cursor_id) {
: idb_cursor_id_(idb_cursor_id),
continue_count_(0),
used_prefetches_(0),
pending_onsuccess_callbacks_(0),
prefetch_amount_(kMinPrefetchAmount) {
}
RendererWebIDBCursorImpl::~RendererWebIDBCursorImpl() {
......@@ -62,6 +66,34 @@ void RendererWebIDBCursorImpl::continueFunction(const WebIDBKey& key,
WebExceptionCode& ec) {
IndexedDBDispatcher* dispatcher =
RenderThreadImpl::current()->indexed_db_dispatcher();
if (key.type() == WebIDBKey::InvalidType) {
// No key, so this would qualify for a prefetch.
++continue_count_;
if (!prefetch_keys_.empty()) {
// We have a prefetch cache, so serve the result from that.
CachedContinue(callbacks);
return;
}
if (continue_count_ > kPrefetchContinueThreshold) {
// Request pre-fetch.
dispatcher->RequestIDBCursorPrefetch(prefetch_amount_, callbacks,
idb_cursor_id_, &ec);
// Increase prefetch_amount_ exponentially.
prefetch_amount_ *= 2;
if (prefetch_amount_ > kMaxPrefetchAmount)
prefetch_amount_ = kMaxPrefetchAmount;
return;
}
} else {
// Key argument supplied. We couldn't prefetch this.
ResetPrefetchCache();
}
dispatcher->RequestIDBCursorContinue(IndexedDBKey(key), callbacks,
idb_cursor_id_, &ec);
}
......@@ -73,6 +105,20 @@ void RendererWebIDBCursorImpl::deleteFunction(WebIDBCallbacks* callbacks,
dispatcher->RequestIDBCursorDelete(callbacks, idb_cursor_id_, &ec);
}
void RendererWebIDBCursorImpl::postSuccessHandlerCallback()
{
pending_onsuccess_callbacks_--;
// If the onsuccess callback called continue() on the cursor again,
// and that continue was served by the prefetch cache, then
// pending_onsuccess_callbacks_ would be incremented.
// If not, it means the callback did something else, or nothing at all,
// in which case we need to reset the cache.
if (pending_onsuccess_callbacks_ == 0)
ResetPrefetchCache();
}
void RendererWebIDBCursorImpl::SetKeyAndValue(
const IndexedDBKey& key,
const IndexedDBKey& primary_key,
......@@ -81,3 +127,55 @@ void RendererWebIDBCursorImpl::SetKeyAndValue(
primary_key_ = primary_key;
value_ = value;
}
void RendererWebIDBCursorImpl::SetPrefetchData(
const std::vector<IndexedDBKey>& keys,
const std::vector<IndexedDBKey>& primary_keys,
const std::vector<content::SerializedScriptValue>& values) {
prefetch_keys_.assign(keys.begin(), keys.end());
prefetch_primary_keys_.assign(primary_keys.begin(), primary_keys.end());
prefetch_values_.assign(values.begin(), values.end());
used_prefetches_ = 0;
pending_onsuccess_callbacks_ = 0;
}
void RendererWebIDBCursorImpl::CachedContinue(
WebKit::WebIDBCallbacks* callbacks) {
DCHECK(prefetch_keys_.size() > 0);
DCHECK(prefetch_primary_keys_.size() == prefetch_keys_.size());
DCHECK(prefetch_values_.size() == prefetch_keys_.size());
key_ = prefetch_keys_.front();
primary_key_ = prefetch_primary_keys_.front();
value_ = prefetch_values_.front();
prefetch_keys_.pop_front();
prefetch_primary_keys_.pop_front();
prefetch_values_.pop_front();
used_prefetches_++;
pending_onsuccess_callbacks_++;
callbacks->onSuccessWithContinuation();
}
void RendererWebIDBCursorImpl::ResetPrefetchCache() {
continue_count_ = 0;
prefetch_amount_ = kMinPrefetchAmount;
if (!prefetch_keys_.size()) {
// No prefetch cache, so no need to reset the cursor in the back-end.
return;
}
IndexedDBDispatcher* dispatcher =
RenderThreadImpl::current()->indexed_db_dispatcher();
dispatcher->RequestIDBCursorPrefetchReset(used_prefetches_,
prefetch_keys_.size(),
idb_cursor_id_);
prefetch_keys_.clear();
prefetch_primary_keys_.clear();
prefetch_values_.clear();
pending_onsuccess_callbacks_ = 0;
}
......@@ -5,6 +5,8 @@
#ifndef CONTENT_RENDERER_RENDERER_WEBIDBCURSOR_IMPL_H_
#define CONTENT_RENDERER_RENDERER_WEBIDBCURSOR_IMPL_H_
#include <deque>
#include "base/basictypes.h"
#include "content/common/indexed_db_key.h"
#include "content/public/common/serialized_script_value.h"
......@@ -30,15 +32,44 @@ class RendererWebIDBCursorImpl : public WebKit::WebIDBCursor {
WebKit::WebExceptionCode& ec);
virtual void deleteFunction(WebKit::WebIDBCallbacks* callback,
WebKit::WebExceptionCode& ec);
virtual void postSuccessHandlerCallback();
void SetKeyAndValue(const IndexedDBKey& key, const IndexedDBKey& primary_key,
const content::SerializedScriptValue& value);
void SetPrefetchData(
const std::vector<IndexedDBKey>& keys,
const std::vector<IndexedDBKey>& primary_keys,
const std::vector<content::SerializedScriptValue>& values);
void CachedContinue(WebKit::WebIDBCallbacks* callbacks);
void ResetPrefetchCache();
private:
int32 idb_cursor_id_;
IndexedDBKey key_;
IndexedDBKey primary_key_;
content::SerializedScriptValue value_;
// Prefetch cache.
std::deque<IndexedDBKey> prefetch_keys_;
std::deque<IndexedDBKey> prefetch_primary_keys_;
std::deque<content::SerializedScriptValue> prefetch_values_;
// Number of continue calls that would qualify for a pre-fetch.
int continue_count_;
// Number of items used from the last prefetch.
int used_prefetches_;
// Number of onsuccess handlers we are waiting for.
int pending_onsuccess_callbacks_;
// Number of items to request in next prefetch.
int prefetch_amount_;
enum { kPrefetchContinueThreshold = 2 };
enum { kMinPrefetchAmount = 5 };
enum { kMaxPrefetchAmount = 100 };
};
#endif // CONTENT_RENDERER_RENDERER_WEBIDBCURSOR_IMPL_H_
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