| Index: content/renderer/renderer_webidbcursor_impl.cc
|
| diff --git a/content/renderer/renderer_webidbcursor_impl.cc b/content/renderer/renderer_webidbcursor_impl.cc
|
| index 5ba7820710180d1be1bd9d50cc584a9e8bb97b0f..58113ad2707909a6805a03225443126bd1015e0a 100644
|
| --- a/content/renderer/renderer_webidbcursor_impl.cc
|
| +++ b/content/renderer/renderer_webidbcursor_impl.cc
|
| @@ -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;
|
| +}
|
|
|