IndexedDB: Optimize single-key get()
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 7 Jun 2012 03:39:35 +0000 (03:39 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 7 Jun 2012 03:39:35 +0000 (03:39 +0000)
https://bugs.webkit.org/show_bug.cgi?id=85288

Patch by Alec Flett <alecflett@chromium.org> on 2012-06-06
Reviewed by Tony Chang.

No new tests, this is just an optimization.

After a recent refactoring, we started creating
an internal cursor with every call to get(). The
most common use of get() is with a single key,
so provide a fast-path to avoid creating the cursor.

* Modules/indexeddb/IDBIndexBackendImpl.cpp:
(WebCore::IDBIndexBackendImpl::getByRangeInternal):
* Modules/indexeddb/IDBKeyRange.h:
(WebCore::IDBKeyRange::isOnlyKey):
(IDBKeyRange):
* Modules/indexeddb/IDBObjectStoreBackendImpl.cpp:
(WebCore::IDBObjectStoreBackendImpl::getByRangeInternal):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@119671 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/Modules/indexeddb/IDBIndexBackendImpl.cpp
Source/WebCore/Modules/indexeddb/IDBKeyRange.h
Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.cpp

index c841fd2..a705bbd 100644 (file)
@@ -1,3 +1,25 @@
+2012-06-06  Alec Flett  <alecflett@chromium.org>
+
+        IndexedDB: Optimize single-key get()
+        https://bugs.webkit.org/show_bug.cgi?id=85288
+
+        Reviewed by Tony Chang.
+
+        No new tests, this is just an optimization.
+
+        After a recent refactoring, we started creating
+        an internal cursor with every call to get(). The
+        most common use of get() is with a single key,
+        so provide a fast-path to avoid creating the cursor.
+
+        * Modules/indexeddb/IDBIndexBackendImpl.cpp:
+        (WebCore::IDBIndexBackendImpl::getByRangeInternal):
+        * Modules/indexeddb/IDBKeyRange.h:
+        (WebCore::IDBKeyRange::isOnlyKey):
+        (IDBKeyRange):
+        * Modules/indexeddb/IDBObjectStoreBackendImpl.cpp:
+        (WebCore::IDBObjectStoreBackendImpl::getByRangeInternal):
+
 2012-06-06  Shezan Baig  <shezbaig.wk@gmail.com>
 
         Caret is not rendered in empty inline contenteditable elements
index 9efe548..6fc3731 100644 (file)
@@ -149,22 +149,27 @@ void IDBIndexBackendImpl::getInternal(ScriptExecutionContext*, PassRefPtr<IDBInd
 {
     IDB_TRACE("IDBIndexBackendImpl::getInternal");
 
-    RefPtr<IDBBackingStore::Cursor> backingStoreCursor =
-            index->backingStore()->openIndexCursor(index->databaseId(), index->m_objectStoreBackend->id(), index->id(), keyRange.get(), IDBCursor::NEXT);
-
-    if (!backingStoreCursor) {
-        callbacks->onSuccess(SerializedScriptValue::undefinedValue());
-        return;
+    RefPtr<IDBKey> key;
+
+    if (keyRange->isOnlyKey())
+        key = keyRange->lower();
+    else {
+        RefPtr<IDBBackingStore::Cursor> backingStoreCursor = index->backingStore()->openIndexCursor(index->databaseId(), index->m_objectStoreBackend->id(), index->id(), keyRange.get(), IDBCursor::NEXT);
+
+        if (!backingStoreCursor) {
+            callbacks->onSuccess(SerializedScriptValue::undefinedValue());
+            return;
+        }
+        key = backingStoreCursor->key();
+        backingStoreCursor->close();
     }
 
-    String value = index->backingStore()->getObjectViaIndex(index->databaseId(), index->m_objectStoreBackend->id(), index->id(), *backingStoreCursor->key());
+    String value = index->backingStore()->getObjectViaIndex(index->databaseId(), index->m_objectStoreBackend->id(), index->id(), *key);
     if (value.isNull()) {
         callbacks->onSuccess(SerializedScriptValue::undefinedValue());
-        backingStoreCursor->close();
         return;
     }
     callbacks->onSuccess(SerializedScriptValue::createFromWire(value));
-    backingStoreCursor->close();
 }
 
 void IDBIndexBackendImpl::getKeyInternal(ScriptExecutionContext* context, PassRefPtr<IDBIndexBackendImpl> index, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks)
index 1d3c5df..8c7909d 100644 (file)
@@ -83,6 +83,11 @@ public:
     }
     static PassRefPtr<IDBKeyRange> bound(PassRefPtr<IDBKey> lower, PassRefPtr<IDBKey> upper, bool lowerOpen, bool upperOpen, ExceptionCode&);
 
+    bool isOnlyKey()
+    {
+        return m_lower == m_upper && m_lowerType == LowerBoundOpen && m_upperType == UpperBoundClosed;
+    }
+
 private:
     IDBKeyRange(PassRefPtr<IDBKey> lower, PassRefPtr<IDBKey> upper, LowerBoundType lowerType, UpperBoundType upperType);
 
index b55d1e1..ac43887 100644 (file)
@@ -95,22 +95,27 @@ void IDBObjectStoreBackendImpl::get(PassRefPtr<IDBKeyRange> prpKeyRange, PassRef
 
 void IDBObjectStoreBackendImpl::getInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks)
 {
-    IDB_TRACE("IDBObjectStoreBackendImpl::getInternal");
-    RefPtr<IDBBackingStore::Cursor> backingStoreCursor = objectStore->backingStore()->openObjectStoreCursor(objectStore->databaseId(), objectStore->id(), keyRange.get(), IDBCursor::NEXT);
-    if (!backingStoreCursor) {
-        callbacks->onSuccess(SerializedScriptValue::undefinedValue());
-        return;
+    IDB_TRACE("IDBObjectStoreBackendImpl::getByRangeInternal");
+    RefPtr<IDBKey> key;
+    if (keyRange->isOnlyKey())
+        key = keyRange->lower();
+    else {
+        RefPtr<IDBBackingStore::Cursor> backingStoreCursor = objectStore->backingStore()->openObjectStoreCursor(objectStore->databaseId(), objectStore->id(), keyRange.get(), IDBCursor::NEXT);
+        if (!backingStoreCursor) {
+            callbacks->onSuccess(SerializedScriptValue::undefinedValue());
+            return;
+        }
+        key = backingStoreCursor->key();
+        backingStoreCursor->close();
     }
 
-    String wireData = objectStore->backingStore()->getObjectStoreRecord(objectStore->databaseId(), objectStore->id(), *backingStoreCursor->key());
+    String wireData = objectStore->backingStore()->getObjectStoreRecord(objectStore->databaseId(), objectStore->id(), *key);
     if (wireData.isNull()) {
         callbacks->onSuccess(SerializedScriptValue::undefinedValue());
-        backingStoreCursor->close();
         return;
     }
 
     callbacks->onSuccess(SerializedScriptValue::createFromWire(wireData));
-    backingStoreCursor->close();
 }
 
 static PassRefPtr<IDBKey> fetchKeyFromKeyPath(SerializedScriptValue* value, const IDBKeyPath& keyPath)