Title: [101645] trunk/Source
Revision
101645
Author
[email protected]
Date
2011-12-01 02:54:37 -0800 (Thu, 01 Dec 2011)

Log Message

IndexedDB: Cursor pre-fetching
https://bugs.webkit.org/show_bug.cgi?id=73025

Reviewed by Darin Fisher.

Source/WebCore:

No new tests. This doesn't change any semantics.
Actual pre-fetching will not happen in DumpRenderTree.
Chromium will request pre-fetching and have tests for it.

* storage/IDBBackingStore.h:
* storage/IDBCallbacks.h:
* storage/IDBCursor.cpp:
(WebCore::IDBCursor::continueFunction):
(WebCore::IDBCursor::postSuccessHandlerCallback):
  Adds a callback that is called everytime the onsuccess handler has
  executed on a cursor. This allows the cursor to see if a new call
  to continue() was made in the onsuccess handler.
* storage/IDBCursor.h:
* storage/IDBCursorBackendImpl.cpp:
(WebCore::IDBCursorBackendImpl::continueFunction):
(WebCore::IDBCursorBackendImpl::prefetchContinue):
(WebCore::IDBCursorBackendImpl::prefetchContinueInternal):
  This is the function that does actual pre-fetching. When called,
  it will attempt to step the cursor up to n steps and send the
  results back via the new onSuccessWithPrefetch() callback.
(WebCore::IDBCursorBackendImpl::prefetchReset):
  This resets the cursor to the position it was at before the last
  prefetch call.
* storage/IDBCursorBackendImpl.h:
(WebCore::IDBCursorBackendImpl::postSuccessHandlerCallback):
* storage/IDBCursorBackendInterface.h:
* storage/IDBKey.h:
(WebCore::IDBKey::createInvalid):
(WebCore::IDBKey::createNumber):
(WebCore::IDBKey::createString):
(WebCore::IDBKey::createDate):
(WebCore::IDBKey::createArray):
(WebCore::IDBKey::sizeEstimate):
* storage/IDBLevelDBBackingStore.cpp:
(WebCore::CursorOptions::CursorImplCommon::CursorImplCommon):
(WebCore::CursorOptions::ObjectStoreCursorImpl::clone):
(WebCore::CursorOptions::ObjectStoreCursorImpl::ObjectStoreCursorImpl):
(WebCore::CursorOptions::IndexKeyCursorImpl::clone):
(WebCore::CursorOptions::IndexKeyCursorImpl::IndexKeyCursorImpl):
(WebCore::CursorOptions::IndexCursorImpl::clone):
(WebCore::CursorOptions::IndexCursorImpl::IndexCursorImpl):
* storage/IDBRequest.cpp:
(WebCore::IDBRequest::dispatchEvent):
  Update dispatchEvent() to call the postSuccessHandlerCallback()
* storage/IDBRequest.h:
(WebCore::IDBRequest::onSuccessWithPrefetch):
* storage/IDBTransactionBackendImpl.cpp:
(WebCore::IDBTransactionBackendImpl::addPendingEvents):
  Allow for adding an arbitrary number of extra pending events.
  When a cursor pre-fetches n elements, the transaction should
  expect to see n extra onsuccess calls.
* storage/IDBTransactionBackendImpl.h:
* storage/IDBTransactionBackendInterface.h:

Source/WebKit/chromium:

Add plumbing for new pre-fetching related functions.

* public/WebIDBCallbacks.h:
(WebKit::WebIDBCallbacks::onSuccessWithPrefetch):
* public/WebIDBCursor.h:
(WebKit::WebIDBCursor::deleteFunction):
(WebKit::WebIDBCursor::prefetchContinue):
(WebKit::WebIDBCursor::prefetchReset):
(WebKit::WebIDBCursor::postSuccessHandlerCallback):
* public/WebIDBTransaction.h:
(WebKit::WebIDBTransaction::addPendingEvents):
* src/IDBCallbacksProxy.cpp:
(WebKit::IDBCallbacksProxy::onSuccessWithPrefetch):
* src/IDBCallbacksProxy.h:
* src/IDBCursorBackendProxy.cpp:
(WebKit::IDBCursorBackendProxy::postSuccessHandlerCallback):
* src/IDBCursorBackendProxy.h:
(WebKit::IDBCursorBackendProxy::prefetchContinue):
(WebKit::IDBCursorBackendProxy::prefetchReset):
* src/IDBTransactionBackendProxy.h:
(WebKit::IDBTransactionBackendProxy::addPendingEvents):
* src/WebIDBCursorImpl.cpp:
(WebKit::WebIDBCursorImpl::prefetchContinue):
(WebKit::WebIDBCursorImpl::prefetchReset):
* src/WebIDBCursorImpl.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (101644 => 101645)


--- trunk/Source/WebCore/ChangeLog	2011-12-01 10:48:27 UTC (rev 101644)
+++ trunk/Source/WebCore/ChangeLog	2011-12-01 10:54:37 UTC (rev 101645)
@@ -1,3 +1,64 @@
+2011-11-29  Hans Wennborg  <[email protected]>
+
+        IndexedDB: Cursor pre-fetching
+        https://bugs.webkit.org/show_bug.cgi?id=73025
+
+        Reviewed by Darin Fisher.
+
+        No new tests. This doesn't change any semantics.
+        Actual pre-fetching will not happen in DumpRenderTree.
+        Chromium will request pre-fetching and have tests for it.
+
+        * storage/IDBBackingStore.h:
+        * storage/IDBCallbacks.h:
+        * storage/IDBCursor.cpp:
+        (WebCore::IDBCursor::continueFunction):
+        (WebCore::IDBCursor::postSuccessHandlerCallback):
+          Adds a callback that is called everytime the onsuccess handler has
+          executed on a cursor. This allows the cursor to see if a new call
+          to continue() was made in the onsuccess handler.
+        * storage/IDBCursor.h:
+        * storage/IDBCursorBackendImpl.cpp:
+        (WebCore::IDBCursorBackendImpl::continueFunction):
+        (WebCore::IDBCursorBackendImpl::prefetchContinue):
+        (WebCore::IDBCursorBackendImpl::prefetchContinueInternal):
+          This is the function that does actual pre-fetching. When called,
+          it will attempt to step the cursor up to n steps and send the
+          results back via the new onSuccessWithPrefetch() callback.
+        (WebCore::IDBCursorBackendImpl::prefetchReset):
+          This resets the cursor to the position it was at before the last
+          prefetch call.
+        * storage/IDBCursorBackendImpl.h:
+        (WebCore::IDBCursorBackendImpl::postSuccessHandlerCallback):
+        * storage/IDBCursorBackendInterface.h:
+        * storage/IDBKey.h:
+        (WebCore::IDBKey::createInvalid):
+        (WebCore::IDBKey::createNumber):
+        (WebCore::IDBKey::createString):
+        (WebCore::IDBKey::createDate):
+        (WebCore::IDBKey::createArray):
+        (WebCore::IDBKey::sizeEstimate):
+        * storage/IDBLevelDBBackingStore.cpp:
+        (WebCore::CursorOptions::CursorImplCommon::CursorImplCommon):
+        (WebCore::CursorOptions::ObjectStoreCursorImpl::clone):
+        (WebCore::CursorOptions::ObjectStoreCursorImpl::ObjectStoreCursorImpl):
+        (WebCore::CursorOptions::IndexKeyCursorImpl::clone):
+        (WebCore::CursorOptions::IndexKeyCursorImpl::IndexKeyCursorImpl):
+        (WebCore::CursorOptions::IndexCursorImpl::clone):
+        (WebCore::CursorOptions::IndexCursorImpl::IndexCursorImpl):
+        * storage/IDBRequest.cpp:
+        (WebCore::IDBRequest::dispatchEvent):
+          Update dispatchEvent() to call the postSuccessHandlerCallback()
+        * storage/IDBRequest.h:
+        (WebCore::IDBRequest::onSuccessWithPrefetch):
+        * storage/IDBTransactionBackendImpl.cpp:
+        (WebCore::IDBTransactionBackendImpl::addPendingEvents):
+          Allow for adding an arbitrary number of extra pending events.
+          When a cursor pre-fetches n elements, the transaction should
+          expect to see n extra onsuccess calls.
+        * storage/IDBTransactionBackendImpl.h:
+        * storage/IDBTransactionBackendInterface.h:
+
 2011-12-01  Philippe Normand  <[email protected]>
 
         [GTK] WebAudio wav resources access and management

Modified: trunk/Source/WebCore/storage/IDBBackingStore.h (101644 => 101645)


--- trunk/Source/WebCore/storage/IDBBackingStore.h	2011-12-01 10:48:27 UTC (rev 101644)
+++ trunk/Source/WebCore/storage/IDBBackingStore.h	2011-12-01 10:54:37 UTC (rev 101645)
@@ -88,6 +88,7 @@
 
     class Cursor : public RefCounted<Cursor> {
     public:
+        virtual PassRefPtr<Cursor> clone() = 0;
         virtual bool continueFunction(const IDBKey* = 0) = 0;
         virtual PassRefPtr<IDBKey> key() = 0;
         virtual PassRefPtr<IDBKey> primaryKey() = 0;

Modified: trunk/Source/WebCore/storage/IDBCallbacks.h (101644 => 101645)


--- trunk/Source/WebCore/storage/IDBCallbacks.h	2011-12-01 10:48:27 UTC (rev 101644)
+++ trunk/Source/WebCore/storage/IDBCallbacks.h	2011-12-01 10:54:37 UTC (rev 101645)
@@ -56,6 +56,7 @@
     virtual void onSuccess(PassRefPtr<IDBTransactionBackendInterface>) = 0;
     virtual void onSuccess(PassRefPtr<SerializedScriptValue>) = 0;
     virtual void onSuccessWithContinuation() = 0;
+    virtual void onSuccessWithPrefetch(const Vector<RefPtr<IDBKey> >& keys, const Vector<RefPtr<IDBKey> >& primaryKeys, const Vector<RefPtr<SerializedScriptValue> >& values) = 0;
     virtual void onBlocked() = 0;
 };
 

Modified: trunk/Source/WebCore/storage/IDBCursor.cpp (101644 => 101645)


--- trunk/Source/WebCore/storage/IDBCursor.cpp	2011-12-01 10:48:27 UTC (rev 101644)
+++ trunk/Source/WebCore/storage/IDBCursor.cpp	2011-12-01 10:54:37 UTC (rev 101645)
@@ -106,8 +106,8 @@
     // FIXME: We're not using the context from when continue was called, which means the callback
     //        will be on the original context openCursor was called on. Is this right?
     if (m_request->resetReadyState(m_transaction.get())) {
+        m_request->setCursor(this);
         m_backend->continueFunction(key, m_request, ec);
-        m_request->setCursor(this);
     } else
         ec = IDBDatabaseException::NOT_ALLOWED_ERR;
 }
@@ -123,6 +123,11 @@
     return request.release();
 }
 
+void IDBCursor::postSuccessHandlerCallback()
+{
+    m_backend->postSuccessHandlerCallback();
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(INDEXED_DATABASE)

Modified: trunk/Source/WebCore/storage/IDBCursor.h (101644 => 101645)


--- trunk/Source/WebCore/storage/IDBCursor.h	2011-12-01 10:48:27 UTC (rev 101644)
+++ trunk/Source/WebCore/storage/IDBCursor.h	2011-12-01 10:54:37 UTC (rev 101645)
@@ -70,6 +70,8 @@
     void continueFunction(PassRefPtr<IDBKey>, ExceptionCode&);
     PassRefPtr<IDBRequest> deleteFunction(ScriptExecutionContext*, ExceptionCode&);
 
+    void postSuccessHandlerCallback();
+
 protected:
     IDBCursor(PassRefPtr<IDBCursorBackendInterface>, IDBRequest*, IDBAny* source, IDBTransaction*);
 

Modified: trunk/Source/WebCore/storage/IDBCursorBackendImpl.cpp (101644 => 101645)


--- trunk/Source/WebCore/storage/IDBCursorBackendImpl.cpp	2011-12-01 10:48:27 UTC (rev 101644)
+++ trunk/Source/WebCore/storage/IDBCursorBackendImpl.cpp	2011-12-01 10:54:37 UTC (rev 101645)
@@ -90,10 +90,8 @@
 
 void IDBCursorBackendImpl::continueFunction(PassRefPtr<IDBKey> prpKey, PassRefPtr<IDBCallbacks> prpCallbacks, ExceptionCode& ec)
 {
-    RefPtr<IDBCursorBackendImpl> cursor = this;
     RefPtr<IDBKey> key = prpKey;
-    RefPtr<IDBCallbacks> callbacks = prpCallbacks;
-    if (!m_transaction->scheduleTask(createCallbackTask(&IDBCursorBackendImpl::continueFunctionInternal, cursor, key, callbacks)))
+    if (!m_transaction->scheduleTask(createCallbackTask(&IDBCursorBackendImpl::continueFunctionInternal, this, key, prpCallbacks)))
         ec = IDBDatabaseException::NOT_ALLOWED_ERR;
 }
 
@@ -123,6 +121,67 @@
     m_objectStore->deleteFunction(m_cursor->primaryKey(), prpCallbacks, m_transaction.get(), ec);
 }
 
+void IDBCursorBackendImpl::prefetchContinue(int numberToFetch, PassRefPtr<IDBCallbacks> prpCallbacks, ExceptionCode& ec)
+{
+    if (!m_transaction->scheduleTask(createCallbackTask(&IDBCursorBackendImpl::prefetchContinueInternal, this, numberToFetch, prpCallbacks)))
+        ec = IDBDatabaseException::NOT_ALLOWED_ERR;
+}
+
+void IDBCursorBackendImpl::prefetchContinueInternal(ScriptExecutionContext*, PassRefPtr<IDBCursorBackendImpl> prpCursor, int numberToFetch, PassRefPtr<IDBCallbacks> callbacks)
+{
+    RefPtr<IDBCursorBackendImpl> cursor = prpCursor;
+
+    Vector<RefPtr<IDBKey> > foundKeys;
+    Vector<RefPtr<IDBKey> > foundPrimaryKeys;
+    Vector<RefPtr<SerializedScriptValue> > foundValues;
+
+    if (cursor->m_cursor)
+        cursor->m_savedCursor = cursor->m_cursor->clone();
+
+    const size_t kMaxSizeEstimate = 10 * 1024 * 1024;
+    size_t sizeEstimate = 0;
+
+    for (int i = 0; i < numberToFetch; ++i) {
+        if (!cursor->m_cursor || !cursor->m_cursor->continueFunction(0)) {
+            cursor->m_cursor = 0;
+            break;
+        }
+
+        foundKeys.append(cursor->m_cursor->key());
+        foundPrimaryKeys.append(cursor->m_cursor->primaryKey());
+        foundValues.append(SerializedScriptValue::createFromWire(cursor->m_cursor->value()));
+
+        sizeEstimate += cursor->m_cursor->key()->sizeEstimate();
+        sizeEstimate += cursor->m_cursor->primaryKey()->sizeEstimate();
+        sizeEstimate += cursor->m_cursor->value().length() * sizeof(UChar);
+
+        if (sizeEstimate > kMaxSizeEstimate)
+            break;
+    }
+
+    if (!foundKeys.size()) {
+        callbacks->onSuccess(SerializedScriptValue::nullValue());
+        return;
+    }
+
+    cursor->m_transaction->addPendingEvents(foundKeys.size() - 1);
+    callbacks->onSuccessWithPrefetch(foundKeys, foundPrimaryKeys, foundValues);
+}
+
+void IDBCursorBackendImpl::prefetchReset(int usedPrefetches, int unusedPrefetches)
+{
+    m_transaction->addPendingEvents(-unusedPrefetches);
+    m_cursor = m_savedCursor;
+    m_savedCursor = 0;
+
+    if (m_cursor) {
+        for (int i = 0; i < usedPrefetches; ++i) {
+            bool ok = m_cursor->continueFunction();
+            ASSERT_UNUSED(ok, ok);
+        }
+    }
+}
+
 void IDBCursorBackendImpl::close()
 {
     if (m_cursor)

Modified: trunk/Source/WebCore/storage/IDBCursorBackendImpl.h (101644 => 101645)


--- trunk/Source/WebCore/storage/IDBCursorBackendImpl.h	2011-12-01 10:48:27 UTC (rev 101644)
+++ trunk/Source/WebCore/storage/IDBCursorBackendImpl.h	2011-12-01 10:54:37 UTC (rev 101645)
@@ -61,14 +61,19 @@
     virtual void update(PassRefPtr<SerializedScriptValue>, PassRefPtr<IDBCallbacks>, ExceptionCode&);
     virtual void continueFunction(PassRefPtr<IDBKey>, PassRefPtr<IDBCallbacks>, ExceptionCode&);
     virtual void deleteFunction(PassRefPtr<IDBCallbacks>, ExceptionCode&);
+    virtual void prefetchContinue(int numberToFetch, PassRefPtr<IDBCallbacks>, ExceptionCode&);
+    virtual void prefetchReset(int usedPrefetches, int unusedPrefetches);
     void close();
+    virtual void postSuccessHandlerCallback() { ASSERT_NOT_REACHED(); }
 
 private:
     IDBCursorBackendImpl(PassRefPtr<IDBBackingStore::Cursor>, IDBCursor::Direction, CursorType, IDBTransactionBackendInterface*, IDBObjectStoreBackendInterface*);
 
     static void continueFunctionInternal(ScriptExecutionContext*, PassRefPtr<IDBCursorBackendImpl>, PassRefPtr<IDBKey>, PassRefPtr<IDBCallbacks>);
+    static void prefetchContinueInternal(ScriptExecutionContext*, PassRefPtr<IDBCursorBackendImpl>, int numberToFetch, PassRefPtr<IDBCallbacks>);
 
     RefPtr<IDBBackingStore::Cursor> m_cursor;
+    RefPtr<IDBBackingStore::Cursor> m_savedCursor;
     IDBCursor::Direction m_direction;
     CursorType m_cursorType;
     RefPtr<IDBTransactionBackendInterface> m_transaction;

Modified: trunk/Source/WebCore/storage/IDBCursorBackendInterface.h (101644 => 101645)


--- trunk/Source/WebCore/storage/IDBCursorBackendInterface.h	2011-12-01 10:48:27 UTC (rev 101644)
+++ trunk/Source/WebCore/storage/IDBCursorBackendInterface.h	2011-12-01 10:54:37 UTC (rev 101645)
@@ -61,6 +61,9 @@
     virtual void update(PassRefPtr<SerializedScriptValue>, PassRefPtr<IDBCallbacks>, ExceptionCode&) = 0;
     virtual void continueFunction(PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks>, ExceptionCode&) = 0;
     virtual void deleteFunction(PassRefPtr<IDBCallbacks>, ExceptionCode&) = 0;
+    virtual void prefetchContinue(int numberToFetch, PassRefPtr<IDBCallbacks>, ExceptionCode&) = 0;
+    virtual void prefetchReset(int usedPrefetches, int unusedPrefetches) = 0;
+    virtual void postSuccessHandlerCallback() = 0;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/storage/IDBKey.cpp (101644 => 101645)


--- trunk/Source/WebCore/storage/IDBKey.cpp	2011-12-01 10:48:27 UTC (rev 101644)
+++ trunk/Source/WebCore/storage/IDBKey.cpp	2011-12-01 10:54:37 UTC (rev 101645)
@@ -32,6 +32,7 @@
 
 IDBKey::IDBKey()
     : m_type(InvalidType)
+    , m_sizeEstimate(kOverheadSize)
 {
 }
 

Modified: trunk/Source/WebCore/storage/IDBKey.h (101644 => 101645)


--- trunk/Source/WebCore/storage/IDBKey.h	2011-12-01 10:48:27 UTC (rev 101644)
+++ trunk/Source/WebCore/storage/IDBKey.h	2011-12-01 10:54:37 UTC (rev 101645)
@@ -51,6 +51,7 @@
         RefPtr<IDBKey> idbKey(new IDBKey());
         idbKey->m_type = NumberType;
         idbKey->m_number = number;
+        idbKey->m_sizeEstimate += sizeof(double);
         return idbKey.release();
     }
 
@@ -59,6 +60,7 @@
         RefPtr<IDBKey> idbKey(new IDBKey());
         idbKey->m_type = StringType;
         idbKey->m_string = string;
+        idbKey->m_sizeEstimate += string.length() * sizeof(UChar);
         return idbKey.release();
     }
 
@@ -67,6 +69,7 @@
         RefPtr<IDBKey> idbKey(new IDBKey());
         idbKey->m_type = DateType;
         idbKey->m_date = date;
+        idbKey->m_sizeEstimate += sizeof(double);
         return idbKey.release();
     }
 
@@ -75,6 +78,10 @@
         RefPtr<IDBKey> idbKey(new IDBKey());
         idbKey->m_type = ArrayType;
         idbKey->m_array = array;
+
+        for (size_t i = 0; i < array.size(); ++i)
+            idbKey->m_sizeEstimate += array[i]->m_sizeEstimate;
+
         return idbKey.release();
     }
 
@@ -121,6 +128,8 @@
     bool isLessThan(const IDBKey* other) const;
     bool isEqual(const IDBKey* other) const;
 
+    size_t sizeEstimate() const { return m_sizeEstimate; }
+
     static int compareTypes(Type a, Type b)
     {
         return b - a;
@@ -137,6 +146,11 @@
     String m_string;
     double m_date;
     double m_number;
+
+    size_t m_sizeEstimate;
+
+    // Very rough estimate of minimum key size overhead.
+    enum { kOverheadSize = 16 };
 };
 
 }

Modified: trunk/Source/WebCore/storage/IDBLevelDBBackingStore.cpp (101644 => 101645)


--- trunk/Source/WebCore/storage/IDBLevelDBBackingStore.cpp	2011-12-01 10:48:27 UTC (rev 101644)
+++ trunk/Source/WebCore/storage/IDBLevelDBBackingStore.cpp	2011-12-01 10:54:37 UTC (rev 101645)
@@ -974,6 +974,22 @@
         , m_cursorOptions(cursorOptions)
     {
     }
+
+    CursorImplCommon(const CursorImplCommon* other)
+        : m_transaction(other->m_transaction)
+        , m_cursorOptions(other->m_cursorOptions)
+        , m_currentKey(other->m_currentKey)
+    {
+        if (other->m_iterator) {
+            m_iterator = m_transaction->createIterator();
+
+            if (other->m_iterator->isValid()) {
+                m_iterator->seek(other->m_iterator->key());
+                ASSERT(m_iterator->isValid());
+            }
+        }
+    }
+
     virtual ~CursorImplCommon() {}
 
     LevelDBTransaction* m_transaction;
@@ -1087,6 +1103,11 @@
         return adoptRef(new ObjectStoreCursorImpl(transaction, cursorOptions));
     }
 
+    virtual PassRefPtr<IDBBackingStore::Cursor> clone()
+    {
+        return adoptRef(new ObjectStoreCursorImpl(this));
+    }
+
     // CursorImplCommon
     virtual String value() { return m_currentValue; }
     virtual PassRefPtr<IDBBackingStore::ObjectStoreRecordIdentifier> objectStoreRecordIdentifier() { ASSERT_NOT_REACHED(); return 0; }
@@ -1099,6 +1120,12 @@
     {
     }
 
+    ObjectStoreCursorImpl(const ObjectStoreCursorImpl* other)
+        : CursorImplCommon(other)
+        , m_currentValue(other->m_currentValue)
+    {
+    }
+
     String m_currentValue;
 };
 
@@ -1134,6 +1161,11 @@
         return adoptRef(new IndexKeyCursorImpl(transaction, cursorOptions));
     }
 
+    virtual PassRefPtr<IDBBackingStore::Cursor> clone()
+    {
+        return adoptRef(new IndexKeyCursorImpl(this));
+    }
+
     // CursorImplCommon
     virtual String value() { ASSERT_NOT_REACHED(); return String(); }
     virtual PassRefPtr<IDBKey> primaryKey() { return m_primaryKey; }
@@ -1147,6 +1179,12 @@
     {
     }
 
+    IndexKeyCursorImpl(const IndexKeyCursorImpl* other)
+        : CursorImplCommon(other)
+        , m_primaryKey(other->m_primaryKey)
+    {
+    }
+
     RefPtr<IDBKey> m_primaryKey;
 };
 
@@ -1197,6 +1235,11 @@
         return adoptRef(new IndexCursorImpl(transaction, cursorOptions));
     }
 
+    virtual PassRefPtr<IDBBackingStore::Cursor> clone()
+    {
+        return adoptRef(new IndexCursorImpl(this));
+    }
+
     // CursorImplCommon
     virtual String value() { return m_value; }
     virtual PassRefPtr<IDBKey> primaryKey() { return m_primaryKey; }
@@ -1210,6 +1253,14 @@
     {
     }
 
+    IndexCursorImpl(const IndexCursorImpl* other)
+        : CursorImplCommon(other)
+        , m_primaryKey(other->m_primaryKey)
+        , m_value(other->m_value)
+        , m_primaryLevelDBKey(other->m_primaryLevelDBKey)
+    {
+    }
+
     RefPtr<IDBKey> m_primaryKey;
     String m_value;
     Vector<char> m_primaryLevelDBKey;

Modified: trunk/Source/WebCore/storage/IDBRequest.cpp (101644 => 101645)


--- trunk/Source/WebCore/storage/IDBRequest.cpp	2011-12-01 10:48:27 UTC (rev 101644)
+++ trunk/Source/WebCore/storage/IDBRequest.cpp	2011-12-01 10:54:37 UTC (rev 101645)
@@ -337,6 +337,14 @@
         targets.append(m_transaction->db());
     }
 
+    RefPtr<IDBCursor> cursorToNotify;
+    if (m_result) {
+        if (m_result->type() == IDBAny::IDBCursorType)
+            cursorToNotify = m_result->idbCursor();
+        else if (m_result->type() == IDBAny::IDBCursorWithValueType)
+            cursorToNotify = m_result->idbCursorWithValue();
+    }
+
     // FIXME: When we allow custom event dispatching, this will probably need to change.
     ASSERT(event->type() == eventNames().successEvent || event->type() == eventNames().errorEvent || event->type() == eventNames().blockedEvent);
     bool dontPreventDefault = IDBEventDispatcher::dispatch(event.get(), targets);
@@ -345,6 +353,9 @@
     if (event->type() != eventNames().blockedEvent && m_result && m_result->type() != IDBAny::IDBCursorType && m_result->type() != IDBAny::IDBCursorWithValueType)
         m_requestFinished = true;
 
+    if (cursorToNotify)
+        cursorToNotify->postSuccessHandlerCallback();
+
     if (m_transaction) {
         // If an error event and the default wasn't prevented...
         if (dontPreventDefault && event->type() == eventNames().errorEvent)

Modified: trunk/Source/WebCore/storage/IDBRequest.h (101644 => 101645)


--- trunk/Source/WebCore/storage/IDBRequest.h	2011-12-01 10:48:27 UTC (rev 101644)
+++ trunk/Source/WebCore/storage/IDBRequest.h	2011-12-01 10:54:37 UTC (rev 101645)
@@ -84,6 +84,7 @@
     virtual void onSuccess(PassRefPtr<IDBTransactionBackendInterface>);
     virtual void onSuccess(PassRefPtr<SerializedScriptValue>);
     virtual void onSuccessWithContinuation();
+    virtual void onSuccessWithPrefetch(const Vector<RefPtr<IDBKey> >& keys, const Vector<RefPtr<IDBKey> >& primaryKeys, const Vector<RefPtr<SerializedScriptValue> >& values) { ASSERT_NOT_REACHED(); } // Not implemented. Callback should not reach the renderer side.
     virtual void onBlocked();
 
     // ActiveDOMObject

Modified: trunk/Source/WebCore/storage/IDBTransactionBackendImpl.cpp (101644 => 101645)


--- trunk/Source/WebCore/storage/IDBTransactionBackendImpl.cpp	2011-12-01 10:48:27 UTC (rev 101644)
+++ trunk/Source/WebCore/storage/IDBTransactionBackendImpl.cpp	2011-12-01 10:54:37 UTC (rev 101645)
@@ -147,6 +147,12 @@
     m_openCursors.remove(cursor);
 }
 
+void IDBTransactionBackendImpl::addPendingEvents(int n)
+{
+    m_pendingEvents += n;
+    ASSERT(m_pendingEvents >= 0);
+}
+
 void IDBTransactionBackendImpl::didCompleteTaskEvents()
 {
     if (m_state == Finished)

Modified: trunk/Source/WebCore/storage/IDBTransactionBackendImpl.h (101644 => 101645)


--- trunk/Source/WebCore/storage/IDBTransactionBackendImpl.h	2011-12-01 10:48:27 UTC (rev 101644)
+++ trunk/Source/WebCore/storage/IDBTransactionBackendImpl.h	2011-12-01 10:54:37 UTC (rev 101645)
@@ -54,6 +54,7 @@
     virtual void setCallbacks(IDBTransactionCallbacks* callbacks) { m_callbacks = callbacks; }
     virtual void registerOpenCursor(IDBCursorBackendImpl*);
     virtual void unregisterOpenCursor(IDBCursorBackendImpl*);
+    virtual void addPendingEvents(int);
 
     void run();
 

Modified: trunk/Source/WebCore/storage/IDBTransactionBackendInterface.h (101644 => 101645)


--- trunk/Source/WebCore/storage/IDBTransactionBackendInterface.h	2011-12-01 10:48:27 UTC (rev 101644)
+++ trunk/Source/WebCore/storage/IDBTransactionBackendInterface.h	2011-12-01 10:54:37 UTC (rev 101645)
@@ -57,6 +57,7 @@
     virtual void setCallbacks(IDBTransactionCallbacks*) = 0;
     virtual void registerOpenCursor(IDBCursorBackendImpl*) = 0;
     virtual void unregisterOpenCursor(IDBCursorBackendImpl*) = 0;
+    virtual void addPendingEvents(int) = 0;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebKit/chromium/ChangeLog (101644 => 101645)


--- trunk/Source/WebKit/chromium/ChangeLog	2011-12-01 10:48:27 UTC (rev 101644)
+++ trunk/Source/WebKit/chromium/ChangeLog	2011-12-01 10:54:37 UTC (rev 101645)
@@ -1,3 +1,36 @@
+2011-11-29  Hans Wennborg  <[email protected]>
+
+        IndexedDB: Cursor pre-fetching
+        https://bugs.webkit.org/show_bug.cgi?id=73025
+
+        Reviewed by Darin Fisher.
+
+        Add plumbing for new pre-fetching related functions.
+
+        * public/WebIDBCallbacks.h:
+        (WebKit::WebIDBCallbacks::onSuccessWithPrefetch):
+        * public/WebIDBCursor.h:
+        (WebKit::WebIDBCursor::deleteFunction):
+        (WebKit::WebIDBCursor::prefetchContinue):
+        (WebKit::WebIDBCursor::prefetchReset):
+        (WebKit::WebIDBCursor::postSuccessHandlerCallback):
+        * public/WebIDBTransaction.h:
+        (WebKit::WebIDBTransaction::addPendingEvents):
+        * src/IDBCallbacksProxy.cpp:
+        (WebKit::IDBCallbacksProxy::onSuccessWithPrefetch):
+        * src/IDBCallbacksProxy.h:
+        * src/IDBCursorBackendProxy.cpp:
+        (WebKit::IDBCursorBackendProxy::postSuccessHandlerCallback):
+        * src/IDBCursorBackendProxy.h:
+        (WebKit::IDBCursorBackendProxy::prefetchContinue):
+        (WebKit::IDBCursorBackendProxy::prefetchReset):
+        * src/IDBTransactionBackendProxy.h:
+        (WebKit::IDBTransactionBackendProxy::addPendingEvents):
+        * src/WebIDBCursorImpl.cpp:
+        (WebKit::WebIDBCursorImpl::prefetchContinue):
+        (WebKit::WebIDBCursorImpl::prefetchReset):
+        * src/WebIDBCursorImpl.h:
+
 2011-12-01  Hans Wennborg  <[email protected]>
 
         IndexedDB: Fix WebIDBObjectStore::createIndex() after r101602

Modified: trunk/Source/WebKit/chromium/public/WebIDBCallbacks.h (101644 => 101645)


--- trunk/Source/WebKit/chromium/public/WebIDBCallbacks.h	2011-12-01 10:48:27 UTC (rev 101644)
+++ trunk/Source/WebKit/chromium/public/WebIDBCallbacks.h	2011-12-01 10:54:37 UTC (rev 101645)
@@ -26,6 +26,7 @@
 #ifndef WebIDBCallbacks_h
 #define WebIDBCallbacks_h
 
+#include "WebVector.h"
 #include "platform/WebCommon.h"
 
 namespace WebKit {
@@ -55,6 +56,7 @@
     virtual void onSuccess(const WebSerializedScriptValue&) { WEBKIT_ASSERT_NOT_REACHED(); }
     virtual void onSuccessWithContinuation() { WEBKIT_ASSERT_NOT_REACHED(); }
     virtual void onBlocked() { WEBKIT_ASSERT_NOT_REACHED(); }
+    virtual void onSuccessWithPrefetch(const WebVector<WebIDBKey>& keys, const WebVector<WebIDBKey>& primaryKeys, const WebVector<WebSerializedScriptValue>& values) { WEBKIT_ASSERT_NOT_REACHED(); }
 };
 
 } // namespace WebKit

Modified: trunk/Source/WebKit/chromium/public/WebIDBCursor.h (101644 => 101645)


--- trunk/Source/WebKit/chromium/public/WebIDBCursor.h	2011-12-01 10:48:27 UTC (rev 101644)
+++ trunk/Source/WebKit/chromium/public/WebIDBCursor.h	2011-12-01 10:54:37 UTC (rev 101645)
@@ -63,7 +63,10 @@
 
     virtual void update(const WebSerializedScriptValue&, WebIDBCallbacks*, WebExceptionCode&) { WEBKIT_ASSERT_NOT_REACHED(); }
     virtual void continueFunction(const WebIDBKey&, WebIDBCallbacks*, WebExceptionCode&) { WEBKIT_ASSERT_NOT_REACHED(); }
-    virtual void deleteFunction(WebIDBCallbacks* callbacks, WebExceptionCode& ec) { WEBKIT_ASSERT_NOT_REACHED(); }
+    virtual void deleteFunction(WebIDBCallbacks*, WebExceptionCode&) { WEBKIT_ASSERT_NOT_REACHED(); }
+    virtual void prefetchContinue(int numberToFetch, WebIDBCallbacks*, WebExceptionCode&) { WEBKIT_ASSERT_NOT_REACHED(); }
+    virtual void prefetchReset(int usedPrefetches, int unusedPrefetches) { WEBKIT_ASSERT_NOT_REACHED(); }
+    virtual void postSuccessHandlerCallback() { } // Only used in frontend.
 
 protected:
     WebIDBCursor() { }

Modified: trunk/Source/WebKit/chromium/public/WebIDBTransaction.h (101644 => 101645)


--- trunk/Source/WebKit/chromium/public/WebIDBTransaction.h	2011-12-01 10:48:27 UTC (rev 101644)
+++ trunk/Source/WebKit/chromium/public/WebIDBTransaction.h	2011-12-01 10:54:37 UTC (rev 101645)
@@ -61,6 +61,8 @@
         return 0;
     }
 
+    virtual void addPendingEvents(int) { WEBKIT_ASSERT_NOT_REACHED(); }
+
 protected:
     WebIDBTransaction() {}
 };

Modified: trunk/Source/WebKit/chromium/src/IDBCallbacksProxy.cpp (101644 => 101645)


--- trunk/Source/WebKit/chromium/src/IDBCallbacksProxy.cpp	2011-12-01 10:48:27 UTC (rev 101644)
+++ trunk/Source/WebKit/chromium/src/IDBCallbacksProxy.cpp	2011-12-01 10:54:37 UTC (rev 101645)
@@ -99,6 +99,23 @@
     m_callbacks->onSuccessWithContinuation();
 }
 
+void IDBCallbacksProxy::onSuccessWithPrefetch(const Vector<RefPtr<IDBKey> >& keys, const Vector<RefPtr<IDBKey> >& primaryKeys, const Vector<RefPtr<SerializedScriptValue> >& values)
+{
+    const size_t n = keys.size();
+
+    WebVector<WebIDBKey> webKeys(n);
+    WebVector<WebIDBKey> webPrimaryKeys(n);
+    WebVector<WebSerializedScriptValue> webValues(n);
+
+    for (size_t i = 0; i < n; ++i) {
+        webKeys[i] = WebIDBKey(keys[i]);
+        webPrimaryKeys[i] = WebIDBKey(primaryKeys[i]);
+        webValues[i] = WebSerializedScriptValue(values[i]);
+    }
+
+    m_callbacks->onSuccessWithPrefetch(webKeys, webPrimaryKeys, webValues);
+}
+
 void IDBCallbacksProxy::onBlocked()
 {
     m_callbacks->onBlocked();

Modified: trunk/Source/WebKit/chromium/src/IDBCallbacksProxy.h (101644 => 101645)


--- trunk/Source/WebKit/chromium/src/IDBCallbacksProxy.h	2011-12-01 10:48:27 UTC (rev 101644)
+++ trunk/Source/WebKit/chromium/src/IDBCallbacksProxy.h	2011-12-01 10:54:37 UTC (rev 101645)
@@ -53,6 +53,7 @@
     virtual void onSuccess(PassRefPtr<WebCore::IDBTransactionBackendInterface>);
     virtual void onSuccess(PassRefPtr<WebCore::SerializedScriptValue>);
     virtual void onSuccessWithContinuation();
+    virtual void onSuccessWithPrefetch(const Vector<RefPtr<WebCore::IDBKey> >& keys, const Vector<RefPtr<WebCore::IDBKey> >& primaryKeys, const Vector<RefPtr<WebCore::SerializedScriptValue> >& values);
     virtual void onBlocked();
 
 private:

Modified: trunk/Source/WebKit/chromium/src/IDBCursorBackendProxy.cpp (101644 => 101645)


--- trunk/Source/WebKit/chromium/src/IDBCursorBackendProxy.cpp	2011-12-01 10:48:27 UTC (rev 101644)
+++ trunk/Source/WebKit/chromium/src/IDBCursorBackendProxy.cpp	2011-12-01 10:54:37 UTC (rev 101645)
@@ -89,6 +89,11 @@
     m_idbCursor->deleteFunction(new WebIDBCallbacksImpl(callbacks), ec);
 }
 
+void IDBCursorBackendProxy::postSuccessHandlerCallback()
+{
+    m_idbCursor->postSuccessHandlerCallback();
+}
+
 } // namespace WebKit
 
 #endif // ENABLE(INDEXED_DATABASE)

Modified: trunk/Source/WebKit/chromium/src/IDBCursorBackendProxy.h (101644 => 101645)


--- trunk/Source/WebKit/chromium/src/IDBCursorBackendProxy.h	2011-12-01 10:48:27 UTC (rev 101644)
+++ trunk/Source/WebKit/chromium/src/IDBCursorBackendProxy.h	2011-12-01 10:54:37 UTC (rev 101645)
@@ -49,6 +49,9 @@
     virtual void update(PassRefPtr<WebCore::SerializedScriptValue>, PassRefPtr<WebCore::IDBCallbacks>, WebCore::ExceptionCode&);
     virtual void continueFunction(PassRefPtr<WebCore::IDBKey>, PassRefPtr<WebCore::IDBCallbacks>, WebCore::ExceptionCode&);
     virtual void deleteFunction(PassRefPtr<WebCore::IDBCallbacks>, WebCore::ExceptionCode&);
+    virtual void prefetchContinue(int numberToFetch, PassRefPtr<WebCore::IDBCallbacks>, WebCore::ExceptionCode&) { ASSERT_NOT_REACHED(); } // Only used in the backend.
+    virtual void prefetchReset(int usedPrefetches, int unusedPrefetches) { ASSERT_NOT_REACHED(); } // Only used in the backend.
+    virtual void postSuccessHandlerCallback();
 
 private:
     IDBCursorBackendProxy(PassOwnPtr<WebIDBCursor>);

Modified: trunk/Source/WebKit/chromium/src/IDBTransactionBackendProxy.h (101644 => 101645)


--- trunk/Source/WebKit/chromium/src/IDBTransactionBackendProxy.h	2011-12-01 10:48:27 UTC (rev 101644)
+++ trunk/Source/WebKit/chromium/src/IDBTransactionBackendProxy.h	2011-12-01 10:54:37 UTC (rev 101645)
@@ -49,6 +49,7 @@
     virtual void setCallbacks(WebCore::IDBTransactionCallbacks*);
     virtual void registerOpenCursor(WebCore::IDBCursorBackendImpl*);
     virtual void unregisterOpenCursor(WebCore::IDBCursorBackendImpl*);
+    virtual void addPendingEvents(int) { ASSERT_NOT_REACHED(); }
 
     WebIDBTransaction* getWebIDBTransaction() const { return m_webIDBTransaction.get(); }
 

Modified: trunk/Source/WebKit/chromium/src/WebIDBCursorImpl.cpp (101644 => 101645)


--- trunk/Source/WebKit/chromium/src/WebIDBCursorImpl.cpp	2011-12-01 10:48:27 UTC (rev 101644)
+++ trunk/Source/WebKit/chromium/src/WebIDBCursorImpl.cpp	2011-12-01 10:54:37 UTC (rev 101645)
@@ -82,6 +82,16 @@
     m_idbCursorBackend->deleteFunction(IDBCallbacksProxy::create(adoptPtr(callbacks)), ec);
 }
 
+void WebIDBCursorImpl::prefetchContinue(int numberToFetch, WebIDBCallbacks* callbacks, WebExceptionCode& ec)
+{
+    m_idbCursorBackend->prefetchContinue(numberToFetch, IDBCallbacksProxy::create(adoptPtr(callbacks)), ec);
+}
+
+void WebIDBCursorImpl::prefetchReset(int usedPrefetches, int unusedPrefetches)
+{
+    m_idbCursorBackend->prefetchReset(usedPrefetches, unusedPrefetches);
+}
+
 } // namespace WebKit
 
 #endif // ENABLE(INDEXED_DATABASE)

Modified: trunk/Source/WebKit/chromium/src/WebIDBCursorImpl.h (101644 => 101645)


--- trunk/Source/WebKit/chromium/src/WebIDBCursorImpl.h	2011-12-01 10:48:27 UTC (rev 101644)
+++ trunk/Source/WebKit/chromium/src/WebIDBCursorImpl.h	2011-12-01 10:54:37 UTC (rev 101645)
@@ -51,6 +51,8 @@
     virtual void update(const WebSerializedScriptValue&, WebIDBCallbacks*, WebExceptionCode&);
     virtual void continueFunction(const WebIDBKey&, WebIDBCallbacks*, WebExceptionCode&);
     virtual void deleteFunction(WebIDBCallbacks*, WebExceptionCode&);
+    virtual void prefetchContinue(int numberToFetch, WebIDBCallbacks*, WebExceptionCode&);
+    virtual void prefetchReset(int usedPrefetches, int unusedPrefetches);
 
  private:
     WTF::RefPtr<WebCore::IDBCursorBackendInterface> m_idbCursorBackend;
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to