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];