Chromium Code Reviews| Index: content/renderer/renderer_webidbcursor_impl.cc |
| diff --git a/content/renderer/renderer_webidbcursor_impl.cc b/content/renderer/renderer_webidbcursor_impl.cc |
| index 8060040a886cdad2a4ec85a515cc61b6d31b2e93..ef88d6b4d45089ae525c43b99c5c61452df15603 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; |
|
jsbell
2011/11/28 20:29:16
Is there any way to check that this hasn't grown t
hans
2011/11/29 14:44:34
Right, this could be a problem. I'll add code to l
|
| + 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_--; |
|
jsbell
2011/11/28 20:29:16
Add DCHECK that pending_onsuccess_callbacks_ >= 0?
dgrogan
2011/11/29 09:08:13
Can pending_onsuccess_callbacks_ ever be > 2?
hans
2011/11/29 14:44:34
It can be negative. The number is decreased for ea
hans
2011/11/29 14:44:34
No, it's always <= 2. Not sure DCHECKing for that
dgrogan
2011/11/30 05:11:06
Agreed, I was asking to make sure I understood wha
|
| + |
| + // If the onsuccess callback called continue() on the cursor again, |
| + // and that continue was served by the prefetch cache, then |
| + // pending_onsuccess_callacks_ would be incremented. |
|
dgrogan
2011/11/29 09:08:13
callbacks_ typo
hans
2011/11/29 14:44:34
Done.
|
| + // 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. |
|
dgrogan
2011/11/29 09:08:13
I might be showing ignorance here, but would this
hans
2011/11/29 14:44:34
You're completely right.
If continue has been cal
|
| + 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; |
| +} |