2 * Copyright (C) 2011 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include "IDBLevelDBCoding.h"
29 #if ENABLE(INDEXED_DATABASE)
33 #include "LevelDBSlice.h"
34 #include <wtf/text/StringBuilder.h>
36 // LevelDB stores key/value pairs. Keys and values are strings of bytes, normally of type Vector<char>.
38 // The keys in the backing store are variable-length tuples with different types
39 // of fields. Each key in the backing store starts with a ternary prefix: (database id, object store id, index id). For each, 0 is reserved for meta-data.
40 // The prefix makes sure that data for a specific database, object store, and index are grouped together. The locality is important for performance: common
41 // operations should only need a minimal number of seek operations. For example, all the meta-data for a database is grouped together so that reading that
42 // meta-data only requires one seek.
44 // Each key type has a class (in square brackets below) which knows how to encode, decode, and compare that key type.
46 // Global meta-data have keys with prefix (0,0,0), followed by a type byte:
48 // <0, 0, 0, 0> => IndexedDB/LevelDB schema version (0 for now) [SchemaVersionKey]
49 // <0, 0, 0, 1> => The maximum database id ever allocated [MaxDatabaseIdKey]
50 // <0, 0, 0, 100, database id> => Existence implies the database id is in the free list [DatabaseFreeListKey]
51 // <0, 0, 0, 201, utf16 origin name, utf16 database name> => Database id [DatabaseNameKey]
54 // Database meta-data:
56 // Again, the prefix is followed by a type byte.
58 // <database id, 0, 0, 0> => utf16 origin name [DatabaseMetaDataKey]
59 // <database id, 0, 0, 1> => utf16 database name [DatabaseMetaDataKey]
60 // <database id, 0, 0, 2> => utf16 user version data [DatabaseMetaDataKey]
61 // <database id, 0, 0, 3> => maximum object store id ever allocated [DatabaseMetaDataKey]
64 // Object store meta-data:
66 // The prefix is followed by a type byte, then a variable-length integer, and then another variable-length integer (FIXME: this should be a byte).
68 // <database id, 0, 0, 50, object store id, 0> => utf16 object store name [ObjectStoreMetaDataKey]
69 // <database id, 0, 0, 50, object store id, 1> => utf16 key path [ObjectStoreMetaDataKey]
70 // <database id, 0, 0, 50, object store id, 2> => has auto increment [ObjectStoreMetaDataKey]
71 // <database id, 0, 0, 50, object store id, 3> => is evictable [ObjectStoreMetaDataKey]
72 // <database id, 0, 0, 50, object store id, 4> => last "version" number [ObjectStoreMetaDataKey]
73 // <database id, 0, 0, 50, object store id, 5> => maximum index id ever allocated [ObjectStoreMetaDataKey]
78 // The prefix is followed by a type byte, then two variable-length integers, and then another type byte.
80 // <database id, 0, 0, 100, object store id, index id, 0> => utf16 index name [IndexMetaDataKey]
81 // <database id, 0, 0, 100, object store id, index id, 1> => are index keys unique [IndexMetaDataKey]
82 // <database id, 0, 0, 100, object store id, index id, 2> => utf16 key path [IndexMetaDataKey]
85 // Other object store and index meta-data:
87 // The prefix is followed by a type byte. The object store and index id are variable length integers, the utf16 strings are variable length strings.
89 // <database id, 0, 0, 150, object store id> => existence implies the object store id is in the free list [ObjectStoreFreeListKey]
90 // <database id, 0, 0, 151, object store id, index id> => existence implies the index id is in the free list [IndexFreeListKey]
91 // <database id, 0, 0, 200, utf16 object store name> => object store id [ObjectStoreNamesKey]
92 // <database id, 0, 0, 201, object store id, utf16 index name> => index id [IndexNamesKey]
97 // The prefix is followed by a type byte. The user key is an encoded IDBKey.
99 // <database id, object store id, 1, user key> => "version", serialized script value [ObjectStoreDataKey]
104 // The prefix is followed by a type byte. The user key is an encoded IDBKey.
106 // <database id, object store id, 2, user key> => "version" [ExistsEntryKey]
111 // The prefix is followed by a type byte. The user key is an encoded IDBKey. The sequence number is a variable length integer.
113 // <database id, object store id, index id, user key, sequence number> => "version", user key [IndexDataKey]
115 // (The sequence number is used to allow two entries with the same user key
116 // in non-unique indexes. The "version" field is used to weed out stale
117 // index data. Whenever new object store data is inserted, it gets a new
118 // "version" number, and new index data is written with this number. When
119 // the index is used for look-ups, entries are validated against the
120 // "exists" entries, and records with old "version" numbers are deleted
121 // when they are encountered in getPrimaryKeyViaIndex,
122 // IndexCursorImpl::loadCurrentRow, and IndexKeyCursorImpl::loadCurrentRow).
125 namespace IDBLevelDBCoding {
127 static const unsigned char kIDBKeyNullTypeByte = 0;
128 static const unsigned char kIDBKeyStringTypeByte = 1;
129 static const unsigned char kIDBKeyDateTypeByte = 2;
130 static const unsigned char kIDBKeyNumberTypeByte = 3;
131 static const unsigned char kIDBKeyMinKeyTypeByte = 4;
133 static const unsigned char kObjectStoreDataIndexId = 1;
134 static const unsigned char kExistsEntryIndexId = 2;
136 static const unsigned char kSchemaVersionTypeByte = 0;
137 static const unsigned char kMaxDatabaseIdTypeByte = 1;
138 static const unsigned char kDatabaseFreeListTypeByte = 100;
139 static const unsigned char kDatabaseNameTypeByte = 201;
141 static const unsigned char kObjectStoreMetaDataTypeByte = 50;
142 static const unsigned char kIndexMetaDataTypeByte = 100;
143 static const unsigned char kObjectStoreFreeListTypeByte = 150;
144 static const unsigned char kIndexFreeListTypeByte = 151;
145 static const unsigned char kObjectStoreNamesTypeByte = 200;
146 static const unsigned char kIndexNamesKeyTypeByte = 201;
149 #define INT64_MAX 0x7fffffffffffffffLL
152 #define INT32_MAX 0x7fffffffL
156 Vector<char> encodeByte(unsigned char c)
163 Vector<char> maxIDBKey()
165 return encodeByte(kIDBKeyNullTypeByte);
168 Vector<char> minIDBKey()
170 return encodeByte(kIDBKeyMinKeyTypeByte);
173 Vector<char> encodeInt(int64_t n)
176 Vector<char> ret; // FIXME: Size this at creation.
187 int64_t decodeInt(const char* begin, const char* end)
189 ASSERT(begin <= end);
193 while (begin < end) {
194 unsigned char c = *begin++;
195 ret |= static_cast<int64_t>(c) << shift;
202 static int compareInts(int64_t a, int64_t b)
207 int64_t diff = a - b;
215 Vector<char> encodeVarInt(int64_t n)
217 Vector<char> ret; // FIXME: Size this at creation.
220 unsigned char c = n & 0x7f;
230 const char* decodeVarInt(const char *p, const char* limit, int64_t& foundInt)
240 unsigned char c = *p;
241 foundInt |= static_cast<int64_t>(c & 0x7f) << shift;
243 } while (*p++ & 0x80);
247 Vector<char> encodeString(const String& s)
249 Vector<char> ret; // FIXME: Size this at creation.
251 for (unsigned i = 0; i < s.length(); ++i) {
253 unsigned char hi = u >> 8;
254 unsigned char lo = u;
262 String decodeString(const char* p, const char* end)
265 ASSERT(!((end - p) % 2));
267 size_t len = (end - p) / 2;
268 StringBuilder result;
269 result.reserveCapacity(len);
271 for (size_t i = 0; i < len; ++i) {
272 unsigned char hi = *p++;
273 unsigned char lo = *p++;
275 result.append(static_cast<UChar>((hi << 8) | lo));
278 return result.toString();
281 Vector<char> encodeStringWithLength(const String& s)
283 Vector<char> ret = encodeVarInt(s.length());
284 ret.append(encodeString(s));
288 const char* decodeStringWithLength(const char* p, const char* limit, String& foundString)
292 p = decodeVarInt(p, limit, len);
295 if (p + len * 2 > limit)
298 foundString = decodeString(p, p + len * 2);
303 Vector<char> encodeDouble(double x)
305 // FIXME: It would be nice if we could be byte order independent.
306 const char* p = reinterpret_cast<char*>(&x);
308 v.append(p, sizeof(x));
309 ASSERT(v.size() == sizeof(x));
313 const char* decodeDouble(const char* p, const char* limit, double* d)
315 if (p + sizeof(*d) > limit)
318 char* x = reinterpret_cast<char*>(d);
319 for (size_t i = 0; i < sizeof(*d); ++i)
324 Vector<char> encodeIDBKey(const IDBKey& key)
328 switch (key.type()) {
329 case IDBKey::NullType:
330 return encodeByte(kIDBKeyNullTypeByte);
331 case IDBKey::StringType:
332 ret = encodeByte(kIDBKeyStringTypeByte);
333 ret.append(encodeStringWithLength(key.string()));
335 case IDBKey::DateType:
336 ret = encodeByte(kIDBKeyDateTypeByte);
337 ret.append(encodeDouble(key.date()));
338 ASSERT(ret.size() == 9);
340 case IDBKey::NumberType:
341 ret = encodeByte(kIDBKeyNumberTypeByte);
342 ret.append(encodeDouble(key.number()));
343 ASSERT(ret.size() == 9);
347 ASSERT_NOT_REACHED();
348 return Vector<char>();
351 const char* decodeIDBKey(const char* p, const char* limit, RefPtr<IDBKey>& foundKey)
357 unsigned char type = *p++;
362 case kIDBKeyNullTypeByte:
364 foundKey = IDBKey::createNull();
366 case kIDBKeyStringTypeByte:
368 p = decodeStringWithLength(p, limit, s);
371 foundKey = IDBKey::createString(s);
373 case kIDBKeyDateTypeByte:
375 p = decodeDouble(p, limit, &d);
378 foundKey = IDBKey::createDate(d);
380 case kIDBKeyNumberTypeByte:
382 p = decodeDouble(p, limit, &d);
385 foundKey = IDBKey::createNumber(d);
389 ASSERT_NOT_REACHED();
393 const char* extractEncodedIDBKey(const char* start, const char* limit, Vector<char>* result)
395 const char* p = start;
399 unsigned char type = *p++;
404 case kIDBKeyNullTypeByte:
405 case kIDBKeyMinKeyTypeByte:
406 *result = encodeByte(type);
408 case kIDBKeyStringTypeByte:
410 p = decodeVarInt(p, limit, stringLen);
413 if (p + stringLen * 2 > limit)
416 result->append(start, p - start + stringLen * 2);
417 return p + stringLen * 2;
418 case kIDBKeyDateTypeByte:
419 case kIDBKeyNumberTypeByte:
421 if (p + sizeof(double) > limit)
424 result->append(start, 1 + sizeof(double));
425 return p + sizeof(double);
427 ASSERT_NOT_REACHED();
431 int compareEncodedIDBKeys(const Vector<char>& keyA, const Vector<char>& keyB)
433 ASSERT(keyA.size() >= 1);
434 ASSERT(keyB.size() >= 1);
436 const char* p = keyA.data();
437 const char* limitA = p + keyA.size();
438 const char* q = keyB.data();
439 const char* limitB = q + keyB.size();
441 unsigned char typeA = *p++;
442 unsigned char typeB = *q++;
447 if (int x = typeB - typeA) // FIXME: Note the subtleness!
451 case kIDBKeyNullTypeByte:
452 case kIDBKeyMinKeyTypeByte:
453 // Null type or max type; no payload to compare.
455 case kIDBKeyStringTypeByte:
457 p = decodeStringWithLength(p, limitA, s); // FIXME: Compare without actually decoding the String!
459 q = decodeStringWithLength(q, limitB, t);
461 return codePointCompare(s, t);
462 case kIDBKeyDateTypeByte:
463 case kIDBKeyNumberTypeByte:
465 p = decodeDouble(p, limitA, &d);
467 q = decodeDouble(q, limitB, &e);
476 ASSERT_NOT_REACHED();
481 template<typename KeyType>
482 int decodeAndCompare(const LevelDBSlice& a, const LevelDBSlice& b)
487 const char* ptrA = KeyType::decode(a.begin(), a.end(), &keyA);
488 ASSERT_UNUSED(ptrA, ptrA);
489 const char* ptrB = KeyType::decode(b.begin(), b.end(), &keyB);
490 ASSERT_UNUSED(ptrB, ptrB);
492 return keyA.compare(keyB);
496 int compare(const LevelDBSlice& a, const LevelDBSlice& b, bool indexKeys)
498 const char* ptrA = a.begin();
499 const char* ptrB = b.begin();
500 const char* endA = a.end();
501 const char* endB = b.end();
506 ptrA = KeyPrefix::decode(ptrA, endA, &prefixA);
507 ptrB = KeyPrefix::decode(ptrB, endB, &prefixB);
511 if (int x = prefixA.compare(prefixB))
514 if (prefixA.type() == KeyPrefix::kGlobalMetaData) {
515 ASSERT(ptrA != endA);
516 ASSERT(ptrB != endB);
518 unsigned char typeByteA = *ptrA++;
519 unsigned char typeByteB = *ptrB++;
521 if (int x = typeByteA - typeByteB)
526 if (typeByteA == kDatabaseFreeListTypeByte)
527 return decodeAndCompare<DatabaseFreeListKey>(a, b);
528 if (typeByteA == kDatabaseNameTypeByte)
529 return decodeAndCompare<DatabaseNameKey>(a, b);
532 if (prefixA.type() == KeyPrefix::kDatabaseMetaData) {
533 ASSERT(ptrA != endA);
534 ASSERT(ptrB != endB);
536 unsigned char typeByteA = *ptrA++;
537 unsigned char typeByteB = *ptrB++;
539 if (int x = typeByteA - typeByteB)
545 if (typeByteA == kObjectStoreMetaDataTypeByte)
546 return decodeAndCompare<ObjectStoreMetaDataKey>(a, b);
547 if (typeByteA == kIndexMetaDataTypeByte)
548 return decodeAndCompare<IndexMetaDataKey>(a, b);
549 if (typeByteA == kObjectStoreFreeListTypeByte)
550 return decodeAndCompare<ObjectStoreFreeListKey>(a, b);
551 if (typeByteA == kIndexFreeListTypeByte)
552 return decodeAndCompare<IndexFreeListKey>(a, b);
553 if (typeByteA == kObjectStoreNamesTypeByte)
554 return decodeAndCompare<ObjectStoreNamesKey>(a, b);
555 if (typeByteA == kIndexNamesKeyTypeByte)
556 return decodeAndCompare<IndexNamesKey>(a, b);
559 ASSERT_NOT_REACHED();
562 if (prefixA.type() == KeyPrefix::kObjectStoreData) {
563 if (ptrA == endA && ptrB == endB)
568 return 1; // FIXME: This case of non-existing user keys should not have to be handled this way.
570 return decodeAndCompare<ObjectStoreDataKey>(a, b);
572 if (prefixA.type() == KeyPrefix::kExistsEntry) {
573 if (ptrA == endA && ptrB == endB)
578 return 1; // FIXME: This case of non-existing user keys should not have to be handled this way.
580 return decodeAndCompare<ExistsEntryKey>(a, b);
582 if (prefixA.type() == KeyPrefix::kIndexData) {
583 if (ptrA == endA && ptrB == endB)
588 return 1; // FIXME: This case of non-existing user keys should not have to be handled this way.
590 IndexDataKey indexDataKeyA;
591 IndexDataKey indexDataKeyB;
593 ptrA = IndexDataKey::decode(a.begin(), endA, &indexDataKeyA);
594 ptrB = IndexDataKey::decode(b.begin(), endB, &indexDataKeyB);
598 bool ignoreSequenceNumber = indexKeys;
599 return indexDataKeyA.compare(indexDataKeyB, ignoreSequenceNumber);
602 ASSERT_NOT_REACHED();
607 KeyPrefix::KeyPrefix()
608 : m_databaseId(kInvalidType)
609 , m_objectStoreId(kInvalidType)
610 , m_indexId(kInvalidType)
614 KeyPrefix::KeyPrefix(int64_t databaseId, int64_t objectStoreId, int64_t indexId)
615 : m_databaseId(databaseId)
616 , m_objectStoreId(objectStoreId)
621 const char* KeyPrefix::decode(const char* start, const char* limit, KeyPrefix* result)
626 unsigned char firstByte = *start++;
628 int databaseIdBytes = ((firstByte >> 5) & 0x7) + 1;
629 int objectStoreIdBytes = ((firstByte >> 2) & 0x7) + 1;
630 int indexIdBytes = (firstByte & 0x3) + 1;
632 if (start + databaseIdBytes + objectStoreIdBytes + indexIdBytes > limit)
635 result->m_databaseId = decodeInt(start, start + databaseIdBytes);
636 start += databaseIdBytes;
637 result->m_objectStoreId = decodeInt(start, start + objectStoreIdBytes);
638 start += objectStoreIdBytes;
639 result->m_indexId = decodeInt(start, start + indexIdBytes);
640 start += indexIdBytes;
645 Vector<char> KeyPrefix::encode() const
647 ASSERT(m_databaseId != kInvalidId);
648 ASSERT(m_objectStoreId != kInvalidId);
649 ASSERT(m_indexId != kInvalidId);
651 Vector<char> databaseIdString = encodeInt(m_databaseId);
652 Vector<char> objectStoreIdString = encodeInt(m_objectStoreId);
653 Vector<char> indexIdString = encodeInt(m_indexId);
655 ASSERT(databaseIdString.size() <= 8);
656 ASSERT(objectStoreIdString.size() <= 8);
657 ASSERT(indexIdString.size() <= 4);
660 unsigned char firstByte = (databaseIdString.size() - 1) << 5 | (objectStoreIdString.size() - 1) << 2 | (indexIdString.size() - 1);
662 ret.append(firstByte);
663 ret.append(databaseIdString);
664 ret.append(objectStoreIdString);
665 ret.append(indexIdString);
670 int KeyPrefix::compare(const KeyPrefix& other) const
672 ASSERT(m_databaseId != kInvalidId);
673 ASSERT(m_objectStoreId != kInvalidId);
674 ASSERT(m_indexId != kInvalidId);
676 if (m_databaseId != other.m_databaseId)
677 return compareInts(m_databaseId, other.m_databaseId);
678 if (m_objectStoreId != other.m_objectStoreId)
679 return compareInts(m_objectStoreId, other.m_objectStoreId);
680 if (m_indexId != other.m_indexId)
681 return compareInts(m_indexId, other.m_indexId);
685 KeyPrefix::Type KeyPrefix::type() const
687 ASSERT(m_databaseId != kInvalidId);
688 ASSERT(m_objectStoreId != kInvalidId);
689 ASSERT(m_indexId != kInvalidId);
692 return kGlobalMetaData;
693 if (!m_objectStoreId)
694 return kDatabaseMetaData;
695 if (m_indexId == kObjectStoreDataIndexId)
696 return kObjectStoreData;
697 if (m_indexId == kExistsEntryIndexId)
699 if (m_indexId >= kMinimumIndexId)
702 ASSERT_NOT_REACHED();
706 Vector<char> SchemaVersionKey::encode()
708 KeyPrefix prefix(0, 0, 0);
709 Vector<char> ret = prefix.encode();
710 ret.append(encodeByte(kSchemaVersionTypeByte));
714 Vector<char> MaxDatabaseIdKey::encode()
716 KeyPrefix prefix(0, 0, 0);
717 Vector<char> ret = prefix.encode();
718 ret.append(encodeByte(kMaxDatabaseIdTypeByte));
722 DatabaseFreeListKey::DatabaseFreeListKey()
727 const char* DatabaseFreeListKey::decode(const char* start, const char* limit, DatabaseFreeListKey* result)
730 const char *p = KeyPrefix::decode(start, limit, &prefix);
733 ASSERT(!prefix.m_databaseId);
734 ASSERT(!prefix.m_objectStoreId);
735 ASSERT(!prefix.m_indexId);
738 unsigned char typeByte = *p++;
739 ASSERT_UNUSED(typeByte, typeByte == kDatabaseFreeListTypeByte);
742 return decodeVarInt(p, limit, result->m_databaseId);
745 Vector<char> DatabaseFreeListKey::encode(int64_t databaseId)
747 KeyPrefix prefix(0, 0, 0);
748 Vector<char> ret = prefix.encode();
749 ret.append(encodeByte(kDatabaseFreeListTypeByte));
750 ret.append(encodeVarInt(databaseId));
754 Vector<char> DatabaseFreeListKey::encodeMaxKey()
756 return encode(INT64_MAX);
759 int64_t DatabaseFreeListKey::databaseId() const
761 ASSERT(m_databaseId >= 0);
765 int DatabaseFreeListKey::compare(const DatabaseFreeListKey& other) const
767 ASSERT(m_databaseId >= 0);
768 return compareInts(m_databaseId, other.m_databaseId);
771 const char* DatabaseNameKey::decode(const char* start, const char* limit, DatabaseNameKey* result)
774 const char* p = KeyPrefix::decode(start, limit, &prefix);
777 ASSERT(!prefix.m_databaseId);
778 ASSERT(!prefix.m_objectStoreId);
779 ASSERT(!prefix.m_indexId);
782 unsigned char typeByte = *p++;
783 ASSERT_UNUSED(typeByte, typeByte == kDatabaseNameTypeByte);
786 p = decodeStringWithLength(p, limit, result->m_origin);
789 return decodeStringWithLength(p, limit, result->m_databaseName);
792 Vector<char> DatabaseNameKey::encode(const String& origin, const String& databaseName)
794 KeyPrefix prefix(0, 0, 0);
795 Vector<char> ret = prefix.encode();
796 ret.append(encodeByte(kDatabaseNameTypeByte));
797 ret.append(encodeStringWithLength(origin));
798 ret.append(encodeStringWithLength(databaseName));
802 int DatabaseNameKey::compare(const DatabaseNameKey& other)
804 if (int x = codePointCompare(m_origin, other.m_origin))
806 return codePointCompare(m_databaseName, other.m_databaseName);
809 Vector<char> DatabaseMetaDataKey::encode(int64_t databaseId, MetaDataType metaDataType)
811 KeyPrefix prefix(databaseId, 0, 0);
812 Vector<char> ret = prefix.encode();
813 ret.append(encodeByte(metaDataType));
817 ObjectStoreMetaDataKey::ObjectStoreMetaDataKey()
818 : m_objectStoreId(-1)
823 const char* ObjectStoreMetaDataKey::decode(const char* start, const char* limit, ObjectStoreMetaDataKey* result)
826 const char* p = KeyPrefix::decode(start, limit, &prefix);
829 ASSERT(prefix.m_databaseId);
830 ASSERT(!prefix.m_objectStoreId);
831 ASSERT(!prefix.m_indexId);
834 unsigned char typeByte = *p++;
835 ASSERT_UNUSED(typeByte, typeByte == kObjectStoreMetaDataTypeByte);
838 p = decodeVarInt(p, limit, result->m_objectStoreId);
841 ASSERT(result->m_objectStoreId);
844 return decodeVarInt(p, limit, result->m_metaDataType);
847 Vector<char> ObjectStoreMetaDataKey::encode(int64_t databaseId, int64_t objectStoreId, int64_t metaDataType)
849 KeyPrefix prefix(databaseId, 0, 0);
850 Vector<char> ret = prefix.encode();
851 ret.append(encodeByte(kObjectStoreMetaDataTypeByte));
852 ret.append(encodeVarInt(objectStoreId));
853 ret.append(encodeVarInt(metaDataType));
857 Vector<char> ObjectStoreMetaDataKey::encodeMaxKey(int64_t databaseId)
859 return encode(databaseId, INT64_MAX, INT64_MAX);
862 int64_t ObjectStoreMetaDataKey::objectStoreId() const
864 ASSERT(m_objectStoreId >= 0);
865 return m_objectStoreId;
867 int64_t ObjectStoreMetaDataKey::metaDataType() const
869 ASSERT(m_metaDataType >= 0);
870 return m_metaDataType;
873 int ObjectStoreMetaDataKey::compare(const ObjectStoreMetaDataKey& other)
875 ASSERT(m_objectStoreId >= 0);
876 ASSERT(m_metaDataType >= 0);
877 if (int x = compareInts(m_objectStoreId, other.m_objectStoreId))
879 return m_metaDataType - other.m_metaDataType;
882 IndexMetaDataKey::IndexMetaDataKey()
883 : m_objectStoreId(-1)
889 const char* IndexMetaDataKey::decode(const char* start, const char* limit, IndexMetaDataKey* result)
892 const char* p = KeyPrefix::decode(start, limit, &prefix);
895 ASSERT(prefix.m_databaseId);
896 ASSERT(!prefix.m_objectStoreId);
897 ASSERT(!prefix.m_indexId);
900 unsigned char typeByte = *p++;
901 ASSERT_UNUSED(typeByte, typeByte == kIndexMetaDataTypeByte);
904 p = decodeVarInt(p, limit, result->m_objectStoreId);
907 p = decodeVarInt(p, limit, result->m_indexId);
912 result->m_metaDataType = *p++;
916 Vector<char> IndexMetaDataKey::encode(int64_t databaseId, int64_t objectStoreId, int64_t indexId, unsigned char metaDataType)
918 KeyPrefix prefix(databaseId, 0, 0);
919 Vector<char> ret = prefix.encode();
920 ret.append(encodeByte(kIndexMetaDataTypeByte));
921 ret.append(encodeVarInt(objectStoreId));
922 ret.append(encodeVarInt(indexId));
923 ret.append(encodeByte(metaDataType));
927 Vector<char> IndexMetaDataKey::encodeMaxKey(int64_t databaseId, int64_t objectStoreId)
929 return encode(databaseId, objectStoreId, INT64_MAX, 255);
932 int IndexMetaDataKey::compare(const IndexMetaDataKey& other)
934 ASSERT(m_objectStoreId >= 0);
935 ASSERT(m_indexId >= 0);
937 if (int x = compareInts(m_objectStoreId, other.m_objectStoreId))
939 if (int x = compareInts(m_indexId, other.m_indexId))
941 return m_metaDataType - other.m_metaDataType;
944 int64_t IndexMetaDataKey::indexId() const
946 ASSERT(m_indexId >= 0);
950 ObjectStoreFreeListKey::ObjectStoreFreeListKey()
951 : m_objectStoreId(-1)
955 const char* ObjectStoreFreeListKey::decode(const char* start, const char* limit, ObjectStoreFreeListKey* result)
958 const char *p = KeyPrefix::decode(start, limit, &prefix);
961 ASSERT(prefix.m_databaseId);
962 ASSERT(!prefix.m_objectStoreId);
963 ASSERT(!prefix.m_indexId);
966 unsigned char typeByte = *p++;
967 ASSERT_UNUSED(typeByte, typeByte == kObjectStoreFreeListTypeByte);
970 return decodeVarInt(p, limit, result->m_objectStoreId);
973 Vector<char> ObjectStoreFreeListKey::encode(int64_t databaseId, int64_t objectStoreId)
975 KeyPrefix prefix(databaseId, 0, 0);
976 Vector<char> ret = prefix.encode();
977 ret.append(encodeByte(kObjectStoreFreeListTypeByte));
978 ret.append(encodeVarInt(objectStoreId));
982 Vector<char> ObjectStoreFreeListKey::encodeMaxKey(int64_t databaseId)
984 return encode(databaseId, INT64_MAX);
987 int64_t ObjectStoreFreeListKey::objectStoreId() const
989 ASSERT(m_objectStoreId >= 0);
990 return m_objectStoreId;
993 int ObjectStoreFreeListKey::compare(const ObjectStoreFreeListKey& other)
995 // FIXME: It may seem strange that we're not comparing database id's,
996 // but that comparison will have been made earlier.
997 // We should probably make this more clear, though...
998 ASSERT(m_objectStoreId >= 0);
999 return compareInts(m_objectStoreId, other.m_objectStoreId);
1002 IndexFreeListKey::IndexFreeListKey()
1003 : m_objectStoreId(-1)
1008 const char* IndexFreeListKey::decode(const char* start, const char* limit, IndexFreeListKey* result)
1011 const char* p = KeyPrefix::decode(start, limit, &prefix);
1014 ASSERT(prefix.m_databaseId);
1015 ASSERT(!prefix.m_objectStoreId);
1016 ASSERT(!prefix.m_indexId);
1019 unsigned char typeByte = *p++;
1020 ASSERT_UNUSED(typeByte, typeByte == kIndexFreeListTypeByte);
1023 p = decodeVarInt(p, limit, result->m_objectStoreId);
1026 return decodeVarInt(p, limit, result->m_indexId);
1029 Vector<char> IndexFreeListKey::encode(int64_t databaseId, int64_t objectStoreId, int64_t indexId)
1031 KeyPrefix prefix(databaseId, 0, 0);
1032 Vector<char> ret = prefix.encode();
1033 ret.append(encodeByte(kIndexFreeListTypeByte));
1034 ret.append(encodeVarInt(objectStoreId));
1035 ret.append(encodeVarInt(indexId));
1039 Vector<char> IndexFreeListKey::encodeMaxKey(int64_t databaseId, int64_t objectStoreId)
1041 return encode(databaseId, objectStoreId, INT64_MAX);
1044 int IndexFreeListKey::compare(const IndexFreeListKey& other)
1046 ASSERT(m_objectStoreId >= 0);
1047 ASSERT(m_indexId >= 0);
1048 if (int x = compareInts(m_objectStoreId, other.m_objectStoreId))
1050 return compareInts(m_indexId, other.m_indexId);
1053 int64_t IndexFreeListKey::objectStoreId() const
1055 ASSERT(m_objectStoreId >= 0);
1056 return m_objectStoreId;
1059 int64_t IndexFreeListKey::indexId() const
1061 ASSERT(m_indexId >= 0);
1065 // FIXME: We never use this to look up object store ids, because a mapping
1066 // is kept in the IDBDatabaseBackendImpl. Can the mapping become unreliable?
1067 // Can we remove this?
1068 const char* ObjectStoreNamesKey::decode(const char* start, const char* limit, ObjectStoreNamesKey* result)
1071 const char* p = KeyPrefix::decode(start, limit, &prefix);
1074 ASSERT(prefix.m_databaseId);
1075 ASSERT(!prefix.m_objectStoreId);
1076 ASSERT(!prefix.m_indexId);
1079 unsigned char typeByte = *p++;
1080 ASSERT_UNUSED(typeByte, typeByte == kObjectStoreNamesTypeByte);
1081 return decodeStringWithLength(p, limit, result->m_objectStoreName);
1084 Vector<char> ObjectStoreNamesKey::encode(int64_t databaseId, const String& objectStoreName)
1086 KeyPrefix prefix(databaseId, 0, 0);
1087 Vector<char> ret = prefix.encode();
1088 ret.append(encodeByte(kObjectStoreNamesTypeByte));
1089 ret.append(encodeStringWithLength(objectStoreName));
1093 int ObjectStoreNamesKey::compare(const ObjectStoreNamesKey& other)
1095 return codePointCompare(m_objectStoreName, other.m_objectStoreName);
1098 IndexNamesKey::IndexNamesKey()
1099 : m_objectStoreId(-1)
1103 // FIXME: We never use this to look up index ids, because a mapping
1104 // is kept at a higher level.
1105 const char* IndexNamesKey::decode(const char* start, const char* limit, IndexNamesKey* result)
1108 const char* p = KeyPrefix::decode(start, limit, &prefix);
1111 ASSERT(prefix.m_databaseId);
1112 ASSERT(!prefix.m_objectStoreId);
1113 ASSERT(!prefix.m_indexId);
1116 unsigned char typeByte = *p++;
1117 ASSERT_UNUSED(typeByte, typeByte == kIndexNamesKeyTypeByte);
1120 p = decodeVarInt(p, limit, result->m_objectStoreId);
1123 return decodeStringWithLength(p, limit, result->m_indexName);
1126 Vector<char> IndexNamesKey::encode(int64_t databaseId, int64_t objectStoreId, const String& indexName)
1128 KeyPrefix prefix(databaseId, 0, 0);
1129 Vector<char> ret = prefix.encode();
1130 ret.append(encodeByte(kIndexNamesKeyTypeByte));
1131 ret.append(encodeVarInt(objectStoreId));
1132 ret.append(encodeStringWithLength(indexName));
1136 int IndexNamesKey::compare(const IndexNamesKey& other)
1138 ASSERT(m_objectStoreId >= 0);
1139 if (int x = compareInts(m_objectStoreId, other.m_objectStoreId))
1141 return codePointCompare(m_indexName, other.m_indexName);
1144 const char* ObjectStoreDataKey::decode(const char* start, const char* end, ObjectStoreDataKey* result)
1147 const char* p = KeyPrefix::decode(start, end, &prefix);
1150 ASSERT(prefix.m_databaseId);
1151 ASSERT(prefix.m_objectStoreId);
1152 ASSERT(prefix.m_indexId == kSpecialIndexNumber);
1155 return extractEncodedIDBKey(p, end, &result->m_encodedUserKey);
1158 Vector<char> ObjectStoreDataKey::encode(int64_t databaseId, int64_t objectStoreId, const Vector<char> encodedUserKey)
1160 KeyPrefix prefix(databaseId, objectStoreId, kSpecialIndexNumber);
1161 Vector<char> ret = prefix.encode();
1162 ret.append(encodedUserKey);
1167 Vector<char> ObjectStoreDataKey::encode(int64_t databaseId, int64_t objectStoreId, const IDBKey& userKey)
1169 return encode(databaseId, objectStoreId, encodeIDBKey(userKey));
1172 int ObjectStoreDataKey::compare(const ObjectStoreDataKey& other)
1174 return compareEncodedIDBKeys(m_encodedUserKey, other.m_encodedUserKey);
1177 PassRefPtr<IDBKey> ObjectStoreDataKey::userKey() const
1180 decodeIDBKey(m_encodedUserKey.begin(), m_encodedUserKey.end(), key);
1184 const int64_t ObjectStoreDataKey::kSpecialIndexNumber = kObjectStoreDataIndexId;
1186 const char* ExistsEntryKey::decode(const char* start, const char* end, ExistsEntryKey* result)
1189 const char* p = KeyPrefix::decode(start, end, &prefix);
1192 ASSERT(prefix.m_databaseId);
1193 ASSERT(prefix.m_objectStoreId);
1194 ASSERT(prefix.m_indexId == kSpecialIndexNumber);
1197 return extractEncodedIDBKey(p, end, &result->m_encodedUserKey);
1200 Vector<char> ExistsEntryKey::encode(int64_t databaseId, int64_t objectStoreId, const Vector<char>& encodedKey)
1202 KeyPrefix prefix(databaseId, objectStoreId, kSpecialIndexNumber);
1203 Vector<char> ret = prefix.encode();
1204 ret.append(encodedKey);
1208 Vector<char> ExistsEntryKey::encode(int64_t databaseId, int64_t objectStoreId, const IDBKey& userKey)
1210 return encode(databaseId, objectStoreId, encodeIDBKey(userKey));
1213 int ExistsEntryKey::compare(const ExistsEntryKey& other)
1215 return compareEncodedIDBKeys(m_encodedUserKey, other.m_encodedUserKey);
1218 PassRefPtr<IDBKey> ExistsEntryKey::userKey() const
1221 decodeIDBKey(m_encodedUserKey.begin(), m_encodedUserKey.end(), key);
1225 const int64_t ExistsEntryKey::kSpecialIndexNumber = kExistsEntryIndexId;
1227 IndexDataKey::IndexDataKey()
1229 , m_objectStoreId(-1)
1231 , m_sequenceNumber(-1)
1235 const char* IndexDataKey::decode(const char* start, const char* limit, IndexDataKey* result)
1238 const char* p = KeyPrefix::decode(start, limit, &prefix);
1241 ASSERT(prefix.m_databaseId);
1242 ASSERT(prefix.m_objectStoreId);
1243 ASSERT(prefix.m_indexId >= kMinimumIndexId);
1244 result->m_databaseId = prefix.m_databaseId;
1245 result->m_objectStoreId = prefix.m_objectStoreId;
1246 result->m_indexId = prefix.m_indexId;
1247 p = extractEncodedIDBKey(p, limit, &result->m_encodedUserKey);
1251 result->m_sequenceNumber = -1; // FIXME: We should change it so that all keys have a sequence number. Shouldn't need to handle this case.
1254 return decodeVarInt(p, limit, result->m_sequenceNumber);
1257 Vector<char> IndexDataKey::encode(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const Vector<char>& encodedUserKey, int64_t sequenceNumber)
1259 KeyPrefix prefix(databaseId, objectStoreId, indexId);
1260 Vector<char> ret = prefix.encode();
1261 ret.append(encodedUserKey);
1262 ret.append(encodeVarInt(sequenceNumber));
1266 Vector<char> IndexDataKey::encode(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey& userKey, int64_t sequenceNumber)
1268 return encode(databaseId, objectStoreId, indexId, encodeIDBKey(userKey), sequenceNumber);
1271 Vector<char> IndexDataKey::encodeMaxKey(int64_t databaseId, int64_t objectStoreId)
1273 return encode(databaseId, objectStoreId, INT32_MAX, maxIDBKey(), INT64_MAX);
1276 int IndexDataKey::compare(const IndexDataKey& other, bool ignoreSequenceNumber)
1278 ASSERT(m_databaseId >= 0);
1279 ASSERT(m_objectStoreId >= 0);
1280 ASSERT(m_indexId >= 0);
1281 if (int x = compareEncodedIDBKeys(m_encodedUserKey, other.m_encodedUserKey))
1283 if (ignoreSequenceNumber)
1285 return compareInts(m_sequenceNumber, other.m_sequenceNumber);
1288 int64_t IndexDataKey::databaseId() const
1290 ASSERT(m_databaseId >= 0);
1291 return m_databaseId;
1294 int64_t IndexDataKey::objectStoreId() const
1296 ASSERT(m_objectStoreId >= 0);
1297 return m_objectStoreId;
1300 int64_t IndexDataKey::indexId() const
1302 ASSERT(m_indexId >= 0);
1306 PassRefPtr<IDBKey> IndexDataKey::userKey() const
1309 decodeIDBKey(m_encodedUserKey.begin(), m_encodedUserKey.end(), key);
1313 } // namespace IDBLevelDBCoding
1314 } // namespace WebCore
1316 #endif // ENABLE(LEVELDB)
1317 #endif // ENABLE(INDEXED_DATABASE)