Title: [95682] trunk
Revision
95682
Author
[email protected]
Date
2011-09-21 16:44:20 -0700 (Wed, 21 Sep 2011)

Log Message

IndexedDB: compare strings without decoding
https://bugs.webkit.org/show_bug.cgi?id=68554

Patch by Joshua Bell <[email protected]> on 2011-09-21
Reviewed by Tony Chang.

Resolves a FIXME in IndexedDB that was also identified as a hotspot
during profiling. Yields a small performance improvement.

* Source/WebCore/storage/IDBLevelDBCoding.cpp:
* Source/WebCore/storage/IDBLevelDBCoding.h:
* Source/WebKit/chromium/tests/IDBLevelDBCodingTest.cpp:

Modified Paths

Diff

Modified: trunk/ChangeLog (95681 => 95682)


--- trunk/ChangeLog	2011-09-21 23:36:35 UTC (rev 95681)
+++ trunk/ChangeLog	2011-09-21 23:44:20 UTC (rev 95682)
@@ -1,5 +1,19 @@
-2011-09-21  Leandro Pereira  <[email protected]>
+2011-09-21  Joshua Bell  <[email protected]>
 
+        IndexedDB: compare strings without decoding
+        https://bugs.webkit.org/show_bug.cgi?id=68554
+
+        Reviewed by Tony Chang.
+
+        Resolves a FIXME in IndexedDB that was also identified as a hotspot
+        during profiling. Yields a small performance improvement.
+
+        * Source/WebCore/storage/IDBLevelDBCoding.cpp:
+        * Source/WebCore/storage/IDBLevelDBCoding.h:
+        * Source/WebKit/chromium/tests/IDBLevelDBCodingTest.cpp:
+
+011-09-21  Leandro Pereira  <[email protected]>
+
         Unreviewed. Remove unused ENABLE_AS_IMAGE flag after r95234 from
         Options{Efl,WinCE}.cmake.
 

Modified: trunk/Source/WebCore/storage/IDBLevelDBCoding.cpp (95681 => 95682)


--- trunk/Source/WebCore/storage/IDBLevelDBCoding.cpp	2011-09-21 23:36:35 UTC (rev 95681)
+++ trunk/Source/WebCore/storage/IDBLevelDBCoding.cpp	2011-09-21 23:44:20 UTC (rev 95682)
@@ -300,6 +300,29 @@
     return p;
 }
 
+int compareEncodedStringsWithLength(const char* p, const char* limitP, const char* q, const char* limitQ)
+{
+    ASSERT(limitP >= p);
+    ASSERT(limitQ >= q);
+    int64_t lenP, lenQ;
+    p = decodeVarInt(p, limitP, lenP);
+    q = decodeVarInt(q, limitQ, lenQ);
+    ASSERT(p && q);
+    ASSERT(lenP >= 0);
+    ASSERT(lenQ >= 0);
+    ASSERT(p + lenP * 2 <= limitP);
+    ASSERT(q + lenQ * 2 <= limitQ);
+
+    const size_t lmin = static_cast<size_t>(lenP < lenQ ? lenP : lenQ);
+    if (int x = memcmp(p, q, lmin * 2))
+        return x;
+
+    if (lenP == lenQ)
+        return 0;
+
+    return (lenP > lenQ) ? 1 : -1;
+}
+
 Vector<char> encodeDouble(double x)
 {
     // FIXME: It would be nice if we could be byte order independent.
@@ -441,7 +464,6 @@
     unsigned char typeA = *p++;
     unsigned char typeB = *q++;
 
-    String s, t;
     double d, e;
 
     if (int x = typeB - typeA) // FIXME: Note the subtleness!
@@ -454,11 +476,7 @@
         return 0;
     case kIDBKeyStringTypeByte:
         // String type.
-        p = decodeStringWithLength(p, limitA, s); // FIXME: Compare without actually decoding the String!
-        ASSERT(p);
-        q = decodeStringWithLength(q, limitB, t);
-        ASSERT(q);
-        return codePointCompare(s, t);
+        return compareEncodedStringsWithLength(p, limitA, q, limitB);
     case kIDBKeyDateTypeByte:
     case kIDBKeyNumberTypeByte:
         // Date or number.

Modified: trunk/Source/WebCore/storage/IDBLevelDBCoding.h (95681 => 95682)


--- trunk/Source/WebCore/storage/IDBLevelDBCoding.h	2011-09-21 23:36:35 UTC (rev 95681)
+++ trunk/Source/WebCore/storage/IDBLevelDBCoding.h	2011-09-21 23:44:20 UTC (rev 95682)
@@ -53,6 +53,7 @@
 String decodeString(const char* p, const char* end);
 Vector<char> encodeStringWithLength(const String&);
 const char* decodeStringWithLength(const char* p, const char* limit, String& foundString);
+int compareEncodedStringsWithLength(const char* p, const char* limitP, const char* q, const char* limitQ);
 Vector<char> encodeDouble(double);
 const char* decodeDouble(const char* p, const char* limit, double*);
 Vector<char> encodeIDBKey(const IDBKey&);

Modified: trunk/Source/WebKit/chromium/tests/IDBLevelDBCodingTest.cpp (95681 => 95682)


--- trunk/Source/WebKit/chromium/tests/IDBLevelDBCodingTest.cpp	2011-09-21 23:36:35 UTC (rev 95681)
+++ trunk/Source/WebKit/chromium/tests/IDBLevelDBCodingTest.cpp	2011-09-21 23:44:20 UTC (rev 95682)
@@ -230,6 +230,55 @@
     }
 }
 
+TEST(IDBLevelDBCodingTest, CompareEncodedStringsWithLength)
+{
+    const UChar testStringA[] = {0x1000, 0x1000, '\0'};
+    const UChar testStringB[] = {0x1000, 0x1000, 0x1000, '\0'};
+    const UChar testStringC[] = {0x1000, 0x1000, 0x1001, '\0'};
+    const UChar testStringD[] = {0x1001, 0x1000, 0x1000, '\0'};
+    const UChar testStringE[] = {0xd834, 0xdd1e, '\0'};
+    const UChar testStringF[] = {0xfffd, '\0'};
+
+    Vector<String> testCases;
+    testCases.append(String(""));
+    testCases.append(String("a"));
+    testCases.append(String("b"));
+    testCases.append(String("baaa"));
+    testCases.append(String("baab"));
+    testCases.append(String("c"));
+    testCases.append(String(testStringA));
+    testCases.append(String(testStringB));
+    testCases.append(String(testStringC));
+    testCases.append(String(testStringD));
+    testCases.append(String(testStringE));
+    testCases.append(String(testStringF));
+
+    for (size_t i = 0; i < testCases.size() - 1; ++i) {
+        String a = testCases[i];
+        String b = testCases[i + 1];
+
+        EXPECT_LT(codePointCompare(a, b), 0);
+        EXPECT_GT(codePointCompare(b, a), 0);
+        EXPECT_EQ(codePointCompare(a, a), 0);
+        EXPECT_EQ(codePointCompare(b, b), 0);
+
+        Vector<char> encodedA = encodeStringWithLength(a);
+        EXPECT_TRUE(encodedA.size());
+        Vector<char> encodedB = encodeStringWithLength(b);
+        EXPECT_TRUE(encodedA.size());
+
+        const char* p = encodedA.data();
+        const char* limitP = p + encodedA.size();
+        const char* q = encodedB.data();
+        const char* limitQ = q + encodedB.size();
+
+        EXPECT_LT(compareEncodedStringsWithLength(p, limitP, q, limitQ), 0);
+        EXPECT_GT(compareEncodedStringsWithLength(q, limitQ, p, limitP), 0);
+        EXPECT_EQ(compareEncodedStringsWithLength(p, limitP, p, limitP), 0);
+        EXPECT_EQ(compareEncodedStringsWithLength(q, limitQ, q, limitQ), 0);
+    }
+}
+
 TEST(IDBLevelDBCodingTest, EncodeDouble)
 {
     EXPECT_EQ(static_cast<size_t>(8), encodeDouble(0).size());
@@ -302,6 +351,8 @@
     keys.append(IDBKey::createString("a"));
     keys.append(IDBKey::createString("b"));
     keys.append(IDBKey::createString("baaa"));
+    keys.append(IDBKey::createString("baab"));
+    keys.append(IDBKey::createString("c"));
 
     for (size_t i = 0; i < keys.size() - 1; ++i) {
         RefPtr<IDBKey> keyA = keys[i];
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to