1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/indexed_db/indexed_db_leveldb_coding.h"
10 #include "base/logging.h"
11 #include "base/strings/string16.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/sys_byteorder.h"
14 #include "content/common/indexed_db/indexed_db_key.h"
15 #include "content/common/indexed_db/indexed_db_key_path.h"
17 // LevelDB Coding Scheme
18 // =====================
20 // LevelDB stores key/value pairs. Keys and values are strings of bytes,
21 // normally of type std::string.
23 // The keys in the backing store are variable-length tuples with different
24 // types of fields. Each key in the backing store starts with a ternary
25 // prefix: (database id, object store id, index id). For each, 0 is reserved
26 // for metadata. See KeyPrefix::Decode() for details of the prefix coding.
28 // The prefix makes sure that data for a specific database, object store, and
29 // index are grouped together. The locality is important for performance:
30 // common operations should only need a minimal number of seek operations. For
31 // example, all the metadata for a database is grouped together so that
32 // reading that metadata only requires one seek.
34 // Each key type has a class (in square brackets below) which knows how to
35 // encode, decode, and compare that key type.
37 // Strings (origins, names, etc) are encoded as UTF-16BE.
42 // The prefix is <0, 0, 0>, followed by a metadata type byte:
44 // <0, 0, 0, 0> => backing store schema version [SchemaVersionKey]
45 // <0, 0, 0, 1> => maximum allocated database [MaxDatabaseIdKey]
46 // <0, 0, 0, 2> => SerializedScriptValue version [DataVersionKey]
47 // <0, 0, 0, 100, database id>
48 // => Existence implies the database id is in the free list
49 // [DatabaseFreeListKey]
50 // <0, 0, 0, 201, origin, database name> => Database id [DatabaseNameKey]
53 // Database metadata: [DatabaseMetaDataKey]
54 // ----------------------------------------
55 // The prefix is <database id, 0, 0> followed by a metadata type byte:
57 // <database id, 0, 0, 0> => origin name
58 // <database id, 0, 0, 1> => database name
59 // <database id, 0, 0, 2> => IDB string version data (obsolete)
60 // <database id, 0, 0, 3> => maximum allocated object store id
61 // <database id, 0, 0, 4> => IDB integer version (var int)
64 // Object store metadata: [ObjectStoreMetaDataKey]
65 // -----------------------------------------------
66 // The prefix is <database id, 0, 0>, followed by a type byte (50), then the
67 // object store id (var int), then a metadata type byte.
69 // <database id, 0, 0, 50, object store id, 0> => object store name
70 // <database id, 0, 0, 50, object store id, 1> => key path
71 // <database id, 0, 0, 50, object store id, 2> => auto increment flag
72 // <database id, 0, 0, 50, object store id, 3> => is evictable
73 // <database id, 0, 0, 50, object store id, 4> => last "version" number
74 // <database id, 0, 0, 50, object store id, 5> => maximum allocated index id
75 // <database id, 0, 0, 50, object store id, 6> => has key path flag (obsolete)
76 // <database id, 0, 0, 50, object store id, 7> => key generator current number
78 // The key path was originally just a string (#1) or null (identified by flag,
79 // #6). To support null, string, or array the coding is now identified by the
80 // leading bytes in #1 - see EncodeIDBKeyPath.
82 // The "version" field is used to weed out stale index data. Whenever new
83 // object store data is inserted, it gets a new "version" number, and new
84 // index data is written with this number. When the index is used for
85 // look-ups, entries are validated against the "exists" entries, and records
86 // with old "version" numbers are deleted when they are encountered in
87 // GetPrimaryKeyViaIndex, IndexCursorImpl::LoadCurrentRow and
88 // IndexKeyCursorImpl::LoadCurrentRow.
91 // Index metadata: [IndexMetaDataKey]
92 // ----------------------------------
93 // The prefix is <database id, 0, 0>, followed by a type byte (100), then the
94 // object store id (var int), then the index id (var int), then a metadata
97 // <database id, 0, 0, 100, object store id, index id, 0> => index name
98 // <database id, 0, 0, 100, object store id, index id, 1> => unique flag
99 // <database id, 0, 0, 100, object store id, index id, 2> => key path
100 // <database id, 0, 0, 100, object store id, index id, 3> => multi-entry flag
103 // Other object store and index metadata
104 // -------------------------------------
105 // The prefix is <database id, 0, 0> followed by a type byte. The object
106 // store and index id are variable length integers, the names are variable
109 // <database id, 0, 0, 150, object store id>
110 // => existence implies the object store id is in the free list
111 // [ObjectStoreFreeListKey]
112 // <database id, 0, 0, 151, object store id, index id>
113 // => existence implies the index id is in the free list [IndexFreeListKey]
114 // <database id, 0, 0, 200, object store name>
115 // => object store id [ObjectStoreNamesKey]
116 // <database id, 0, 0, 201, object store id, index name>
117 // => index id [IndexNamesKey]
120 // Object store data: [ObjectStoreDataKey]
121 // ---------------------------------------
122 // The prefix is followed by a type byte and the encoded IDB primary key. The
123 // data has a "version" prefix followed by the serialized script value.
125 // <database id, object store id, 1, user key>
126 // => "version", serialized script value
129 // "Exists" entry: [ExistsEntryKey]
130 // --------------------------------
131 // The prefix is followed by a type byte and the encoded IDB primary key.
133 // <database id, object store id, 2, user key> => "version"
138 // The prefix is followed by a type byte, the encoded IDB index key, a
139 // "sequence" number (obsolete; var int), and the encoded IDB primary key.
141 // <database id, object store id, index id, index key, sequence number,
142 // primary key> => "version", primary key [IndexDataKey]
144 // The sequence number is obsolete; it was used to allow two entries with the
145 // same user (index) key in non-unique indexes prior to the inclusion of the
146 // primary key in the data.
149 using base::StringPiece
;
150 using WebKit::WebIDBKeyType
;
151 using WebKit::WebIDBKeyTypeArray
;
152 using WebKit::WebIDBKeyTypeDate
;
153 using WebKit::WebIDBKeyTypeInvalid
;
154 using WebKit::WebIDBKeyTypeMin
;
155 using WebKit::WebIDBKeyTypeNull
;
156 using WebKit::WebIDBKeyTypeNumber
;
157 using WebKit::WebIDBKeyTypeString
;
158 using WebKit::WebIDBKeyPathType
;
159 using WebKit::WebIDBKeyPathTypeArray
;
160 using WebKit::WebIDBKeyPathTypeNull
;
161 using WebKit::WebIDBKeyPathTypeString
;
165 // As most of the IndexedDBKeys and encoded values are short, we
166 // initialize some Vectors with a default inline buffer size to reduce
167 // the memory re-allocations when the Vectors are appended.
168 static const size_t kDefaultInlineBufferSize
= 32;
170 static const unsigned char kIndexedDBKeyNullTypeByte
= 0;
171 static const unsigned char kIndexedDBKeyStringTypeByte
= 1;
172 static const unsigned char kIndexedDBKeyDateTypeByte
= 2;
173 static const unsigned char kIndexedDBKeyNumberTypeByte
= 3;
174 static const unsigned char kIndexedDBKeyArrayTypeByte
= 4;
175 static const unsigned char kIndexedDBKeyMinKeyTypeByte
= 5;
177 static const unsigned char kIndexedDBKeyPathTypeCodedByte1
= 0;
178 static const unsigned char kIndexedDBKeyPathTypeCodedByte2
= 0;
180 static const unsigned char kObjectStoreDataIndexId
= 1;
181 static const unsigned char kExistsEntryIndexId
= 2;
183 static const unsigned char kSchemaVersionTypeByte
= 0;
184 static const unsigned char kMaxDatabaseIdTypeByte
= 1;
185 static const unsigned char kDataVersionTypeByte
= 2;
186 static const unsigned char kMaxSimpleGlobalMetaDataTypeByte
=
187 3; // Insert before this and increment.
188 static const unsigned char kDatabaseFreeListTypeByte
= 100;
189 static const unsigned char kDatabaseNameTypeByte
= 201;
191 static const unsigned char kObjectStoreMetaDataTypeByte
= 50;
192 static const unsigned char kIndexMetaDataTypeByte
= 100;
193 static const unsigned char kObjectStoreFreeListTypeByte
= 150;
194 static const unsigned char kIndexFreeListTypeByte
= 151;
195 static const unsigned char kObjectStoreNamesTypeByte
= 200;
196 static const unsigned char kIndexNamesKeyTypeByte
= 201;
198 static const unsigned char kObjectMetaDataTypeMaximum
= 255;
199 static const unsigned char kIndexMetaDataTypeMaximum
= 255;
201 const unsigned char kMinimumIndexId
= 30;
203 inline void EncodeIntSafely(int64 nParam
, int64 max
, std::string
* into
) {
204 DCHECK_LE(nParam
, max
);
205 return EncodeInt(nParam
, into
);
208 std::string
MaxIDBKey() {
210 EncodeByte(kIndexedDBKeyNullTypeByte
, &ret
);
214 std::string
MinIDBKey() {
216 EncodeByte(kIndexedDBKeyMinKeyTypeByte
, &ret
);
220 void EncodeByte(unsigned char value
, std::string
* into
) {
221 into
->push_back(value
);
224 void EncodeBool(bool value
, std::string
* into
) {
225 into
->push_back(value
? 1 : 0);
228 void EncodeInt(int64 value
, std::string
* into
) {
230 // Exercised by unit tests in debug only.
233 uint64 n
= static_cast<uint64
>(value
);
242 void EncodeVarInt(int64 value
, std::string
* into
) {
244 // Exercised by unit tests in debug only.
247 uint64 n
= static_cast<uint64
>(value
);
250 unsigned char c
= n
& 0x7f;
258 void EncodeString(const string16
& value
, std::string
* into
) {
261 // Backing store is UTF-16BE, convert from host endianness.
262 size_t length
= value
.length();
263 size_t current
= into
->size();
264 into
->resize(into
->size() + length
* sizeof(char16
));
266 const char16
* src
= value
.c_str();
267 char16
* dst
= reinterpret_cast<char16
*>(&*into
->begin() + current
);
268 for (unsigned i
= 0; i
< length
; ++i
)
269 *dst
++ = htons(*src
++);
272 void EncodeStringWithLength(const string16
& value
, std::string
* into
) {
273 EncodeVarInt(value
.length(), into
);
274 EncodeString(value
, into
);
277 void EncodeDouble(double value
, std::string
* into
) {
278 // This always has host endianness.
279 const char* p
= reinterpret_cast<char*>(&value
);
280 into
->insert(into
->end(), p
, p
+ sizeof(value
));
283 void EncodeIDBKey(const IndexedDBKey
& value
, std::string
* into
) {
284 size_t previous_size
= into
->size();
285 DCHECK(value
.IsValid());
286 switch (value
.type()) {
287 case WebIDBKeyTypeNull
:
288 case WebIDBKeyTypeInvalid
:
289 case WebIDBKeyTypeMin
: {
291 EncodeByte(kIndexedDBKeyNullTypeByte
, into
);
294 case WebIDBKeyTypeArray
: {
295 EncodeByte(kIndexedDBKeyArrayTypeByte
, into
);
296 size_t length
= value
.array().size();
297 EncodeVarInt(length
, into
);
298 for (size_t i
= 0; i
< length
; ++i
)
299 EncodeIDBKey(value
.array()[i
], into
);
300 DCHECK_GT(into
->size(), previous_size
);
303 case WebIDBKeyTypeString
: {
304 EncodeByte(kIndexedDBKeyStringTypeByte
, into
);
305 EncodeStringWithLength(value
.string(), into
);
306 DCHECK_GT(into
->size(), previous_size
);
309 case WebIDBKeyTypeDate
: {
310 EncodeByte(kIndexedDBKeyDateTypeByte
, into
);
311 EncodeDouble(value
.date(), into
);
312 DCHECK_EQ(static_cast<size_t>(9),
313 static_cast<size_t>(into
->size() - previous_size
));
316 case WebIDBKeyTypeNumber
: {
317 EncodeByte(kIndexedDBKeyNumberTypeByte
, into
);
318 EncodeDouble(value
.number(), into
);
319 DCHECK_EQ(static_cast<size_t>(9),
320 static_cast<size_t>(into
->size() - previous_size
));
328 void EncodeIDBKeyPath(const IndexedDBKeyPath
& value
, std::string
* into
) {
329 // May be typed, or may be a raw string. An invalid leading
330 // byte is used to identify typed coding. New records are
331 // always written as typed.
332 EncodeByte(kIndexedDBKeyPathTypeCodedByte1
, into
);
333 EncodeByte(kIndexedDBKeyPathTypeCodedByte2
, into
);
334 EncodeByte(static_cast<char>(value
.type()), into
);
335 switch (value
.type()) {
336 case WebIDBKeyPathTypeNull
:
338 case WebIDBKeyPathTypeString
: {
339 EncodeStringWithLength(value
.string(), into
);
342 case WebIDBKeyPathTypeArray
: {
343 const std::vector
<string16
>& array
= value
.array();
344 size_t count
= array
.size();
345 EncodeVarInt(count
, into
);
346 for (size_t i
= 0; i
< count
; ++i
) {
347 EncodeStringWithLength(array
[i
], into
);
354 bool DecodeByte(StringPiece
* slice
, unsigned char* value
) {
358 *value
= (*slice
)[0];
359 slice
->remove_prefix(1);
363 bool DecodeBool(StringPiece
* slice
, bool* value
) {
367 *value
= !!(*slice
)[0];
368 slice
->remove_prefix(1);
372 bool DecodeInt(StringPiece
* slice
, int64
* value
) {
376 StringPiece::const_iterator it
= slice
->begin();
379 while (it
!= slice
->end()) {
380 unsigned char c
= *it
++;
381 ret
|= static_cast<int64
>(c
) << shift
;
385 slice
->remove_prefix(it
- slice
->begin());
389 bool DecodeVarInt(StringPiece
* slice
, int64
* value
) {
393 StringPiece::const_iterator it
= slice
->begin();
397 if (it
== slice
->end())
400 unsigned char c
= *it
;
401 ret
|= static_cast<int64
>(c
& 0x7f) << shift
;
403 } while (*it
++ & 0x80);
405 slice
->remove_prefix(it
- slice
->begin());
409 bool DecodeString(StringPiece
* slice
, string16
* value
) {
410 if (slice
->empty()) {
415 // Backing store is UTF-16BE, convert to host endianness.
416 DCHECK(!(slice
->size() % sizeof(char16
)));
417 size_t length
= slice
->size() / sizeof(char16
);
419 decoded
.reserve(length
);
420 const char16
* encoded
= reinterpret_cast<const char16
*>(slice
->begin());
421 for (unsigned i
= 0; i
< length
; ++i
)
422 decoded
.push_back(ntohs(*encoded
++));
425 slice
->remove_prefix(length
* sizeof(char16
));
429 bool DecodeStringWithLength(StringPiece
* slice
, string16
* value
) {
434 if (!DecodeVarInt(slice
, &length
) || length
< 0)
436 size_t bytes
= length
* sizeof(char16
);
437 if (slice
->size() < bytes
)
440 StringPiece
subpiece(slice
->begin(), bytes
);
441 slice
->remove_prefix(bytes
);
442 if (!DecodeString(&subpiece
, value
))
448 bool DecodeIDBKey(StringPiece
* slice
, scoped_ptr
<IndexedDBKey
>* value
) {
452 unsigned char type
= (*slice
)[0];
453 slice
->remove_prefix(1);
456 case kIndexedDBKeyNullTypeByte
:
457 *value
= make_scoped_ptr(new IndexedDBKey());
460 case kIndexedDBKeyArrayTypeByte
: {
462 if (!DecodeVarInt(slice
, &length
) || length
< 0)
464 IndexedDBKey::KeyArray array
;
466 scoped_ptr
<IndexedDBKey
> key
;
467 if (!DecodeIDBKey(slice
, &key
))
469 array
.push_back(*key
);
471 *value
= make_scoped_ptr(new IndexedDBKey(array
));
474 case kIndexedDBKeyStringTypeByte
: {
476 if (!DecodeStringWithLength(slice
, &s
))
478 *value
= make_scoped_ptr(new IndexedDBKey(s
));
481 case kIndexedDBKeyDateTypeByte
: {
483 if (!DecodeDouble(slice
, &d
))
485 *value
= make_scoped_ptr(new IndexedDBKey(d
, WebIDBKeyTypeDate
));
488 case kIndexedDBKeyNumberTypeByte
: {
490 if (!DecodeDouble(slice
, &d
))
492 *value
= make_scoped_ptr(new IndexedDBKey(d
, WebIDBKeyTypeNumber
));
501 bool DecodeDouble(StringPiece
* slice
, double* value
) {
502 if (slice
->size() < sizeof(*value
))
505 memcpy(value
, slice
->begin(), sizeof(*value
));
506 slice
->remove_prefix(sizeof(*value
));
510 bool DecodeIDBKeyPath(StringPiece
* slice
, IndexedDBKeyPath
* value
) {
511 // May be typed, or may be a raw string. An invalid leading
512 // byte sequence is used to identify typed coding. New records are
513 // always written as typed.
514 if (slice
->size() < 3 || (*slice
)[0] != kIndexedDBKeyPathTypeCodedByte1
||
515 (*slice
)[1] != kIndexedDBKeyPathTypeCodedByte2
) {
517 if (!DecodeString(slice
, &s
))
519 *value
= IndexedDBKeyPath(s
);
523 slice
->remove_prefix(2);
524 DCHECK(!slice
->empty());
525 WebIDBKeyPathType type
= static_cast<WebIDBKeyPathType
>((*slice
)[0]);
526 slice
->remove_prefix(1);
529 case WebIDBKeyPathTypeNull
:
530 DCHECK(slice
->empty());
531 *value
= IndexedDBKeyPath();
533 case WebIDBKeyPathTypeString
: {
535 if (!DecodeStringWithLength(slice
, &string
))
537 DCHECK(slice
->empty());
538 *value
= IndexedDBKeyPath(string
);
541 case WebIDBKeyPathTypeArray
: {
542 std::vector
<string16
> array
;
544 if (!DecodeVarInt(slice
, &count
))
549 if (!DecodeStringWithLength(slice
, &string
))
551 array
.push_back(string
);
553 DCHECK(slice
->empty());
554 *value
= IndexedDBKeyPath(array
);
562 bool ConsumeEncodedIDBKey(StringPiece
* slice
) {
563 unsigned char type
= (*slice
)[0];
564 slice
->remove_prefix(1);
567 case kIndexedDBKeyNullTypeByte
:
568 case kIndexedDBKeyMinKeyTypeByte
:
570 case kIndexedDBKeyArrayTypeByte
: {
572 if (!DecodeVarInt(slice
, &length
))
575 if (!ConsumeEncodedIDBKey(slice
))
580 case kIndexedDBKeyStringTypeByte
: {
582 if (!DecodeVarInt(slice
, &length
) || length
< 0)
584 if (slice
->size() < static_cast<size_t>(length
) * sizeof(char16
))
586 slice
->remove_prefix(length
* sizeof(char16
));
589 case kIndexedDBKeyDateTypeByte
:
590 case kIndexedDBKeyNumberTypeByte
:
591 if (slice
->size() < sizeof(double))
593 slice
->remove_prefix(sizeof(double));
600 bool ExtractEncodedIDBKey(StringPiece
* slice
, std::string
* result
) {
601 const char* start
= slice
->begin();
602 if (!ConsumeEncodedIDBKey(slice
))
606 result
->assign(start
, slice
->begin());
610 static WebIDBKeyType
KeyTypeByteToKeyType(unsigned char type
) {
612 case kIndexedDBKeyNullTypeByte
:
613 return WebIDBKeyTypeInvalid
;
614 case kIndexedDBKeyArrayTypeByte
:
615 return WebIDBKeyTypeArray
;
616 case kIndexedDBKeyStringTypeByte
:
617 return WebIDBKeyTypeString
;
618 case kIndexedDBKeyDateTypeByte
:
619 return WebIDBKeyTypeDate
;
620 case kIndexedDBKeyNumberTypeByte
:
621 return WebIDBKeyTypeNumber
;
622 case kIndexedDBKeyMinKeyTypeByte
:
623 return WebIDBKeyTypeMin
;
627 return WebIDBKeyTypeInvalid
;
630 int CompareEncodedStringsWithLength(StringPiece
* slice1
,
634 if (!DecodeVarInt(slice1
, &len1
) || !DecodeVarInt(slice2
, &len2
)) {
640 if (len1
< 0 || len2
< 0) {
644 DCHECK_GE(slice1
->size(), len1
* sizeof(char16
));
645 DCHECK_GE(slice2
->size(), len2
* sizeof(char16
));
646 if (slice1
->size() < len1
* sizeof(char16
) ||
647 slice2
->size() < len2
* sizeof(char16
)) {
652 StringPiece
string1(slice1
->begin(), len1
* sizeof(char16
));
653 StringPiece
string2(slice2
->begin(), len2
* sizeof(char16
));
654 slice1
->remove_prefix(len1
* sizeof(char16
));
655 slice2
->remove_prefix(len2
* sizeof(char16
));
658 // Strings are UTF-16BE encoded, so a simple memcmp is sufficient.
659 return string1
.compare(string2
);
662 static int CompareInts(int64 a
, int64 b
) {
664 // Exercised by unit tests in debug only.
676 static inline int CompareSizes(size_t a
, size_t b
) {
684 static int CompareTypes(WebIDBKeyType a
, WebIDBKeyType b
) { return b
- a
; }
686 int CompareEncodedIDBKeys(StringPiece
* slice_a
,
687 StringPiece
* slice_b
,
689 DCHECK(!slice_a
->empty());
690 DCHECK(!slice_b
->empty());
692 unsigned char type_a
= (*slice_a
)[0];
693 unsigned char type_b
= (*slice_b
)[0];
694 slice_a
->remove_prefix(1);
695 slice_b
->remove_prefix(1);
697 if (int x
= CompareTypes(KeyTypeByteToKeyType(type_a
),
698 KeyTypeByteToKeyType(type_b
)))
702 case kIndexedDBKeyNullTypeByte
:
703 case kIndexedDBKeyMinKeyTypeByte
:
704 // Null type or max type; no payload to compare.
706 case kIndexedDBKeyArrayTypeByte
: {
707 int64 length_a
, length_b
;
708 if (!DecodeVarInt(slice_a
, &length_a
) ||
709 !DecodeVarInt(slice_b
, &length_b
)) {
713 for (int64 i
= 0; i
< length_a
&& i
< length_b
; ++i
) {
714 int result
= CompareEncodedIDBKeys(slice_a
, slice_b
, ok
);
718 return length_a
- length_b
;
720 case kIndexedDBKeyStringTypeByte
:
721 return CompareEncodedStringsWithLength(slice_a
, slice_b
, ok
);
722 case kIndexedDBKeyDateTypeByte
:
723 case kIndexedDBKeyNumberTypeByte
: {
725 if (!DecodeDouble(slice_a
, &d
) || !DecodeDouble(slice_b
, &e
)) {
741 int CompareEncodedIDBKeys(const std::string
& key_a
,
742 const std::string
& key_b
,
744 DCHECK(!key_a
.empty());
745 DCHECK(!key_b
.empty());
747 StringPiece
slice_a(key_a
);
748 StringPiece
slice_b(key_b
);
749 return CompareEncodedIDBKeys(&slice_a
, &slice_b
, ok
);
754 template <typename KeyType
>
755 int Compare(const StringPiece
& a
,
756 const StringPiece
& b
,
757 bool only_compare_index_keys
,
762 StringPiece
slice_a(a
);
763 if (!KeyType::Decode(&slice_a
, &key_a
)) {
767 StringPiece
slice_b(b
);
768 if (!KeyType::Decode(&slice_b
, &key_b
)) {
774 return key_a
.Compare(key_b
);
777 template <typename KeyType
>
778 int CompareSuffix(StringPiece
* a
,
780 bool only_compare_index_keys
,
787 int CompareSuffix
<ExistsEntryKey
>(StringPiece
* slice_a
,
788 StringPiece
* slice_b
,
789 bool only_compare_index_keys
,
791 DCHECK(!slice_a
->empty());
792 DCHECK(!slice_b
->empty());
793 return CompareEncodedIDBKeys(slice_a
, slice_b
, ok
);
797 int Compare
<ExistsEntryKey
>(const StringPiece
& a
,
798 const StringPiece
& b
,
799 bool only_compare_index_keys
,
803 StringPiece
slice_a(a
);
804 StringPiece
slice_b(b
);
805 bool ok_a
= KeyPrefix::Decode(&slice_a
, &prefix_a
);
806 bool ok_b
= KeyPrefix::Decode(&slice_b
, &prefix_b
);
809 DCHECK(prefix_a
.database_id_
);
810 DCHECK(prefix_a
.object_store_id_
);
811 DCHECK_EQ(prefix_a
.index_id_
, ExistsEntryKey::kSpecialIndexNumber
);
812 DCHECK(prefix_b
.database_id_
);
813 DCHECK(prefix_b
.object_store_id_
);
814 DCHECK_EQ(prefix_b
.index_id_
, ExistsEntryKey::kSpecialIndexNumber
);
815 DCHECK(!slice_a
.empty());
816 DCHECK(!slice_b
.empty());
817 // Prefixes are not compared - it is assumed this was already done.
818 DCHECK(!prefix_a
.Compare(prefix_b
));
820 return CompareSuffix
<ExistsEntryKey
>(
821 &slice_a
, &slice_b
, only_compare_index_keys
, ok
);
825 int CompareSuffix
<ObjectStoreDataKey
>(StringPiece
* slice_a
,
826 StringPiece
* slice_b
,
827 bool only_compare_index_keys
,
829 return CompareEncodedIDBKeys(slice_a
, slice_b
, ok
);
833 int Compare
<ObjectStoreDataKey
>(const StringPiece
& a
,
834 const StringPiece
& b
,
835 bool only_compare_index_keys
,
839 StringPiece
slice_a(a
);
840 StringPiece
slice_b(b
);
841 bool ok_a
= KeyPrefix::Decode(&slice_a
, &prefix_a
);
842 bool ok_b
= KeyPrefix::Decode(&slice_b
, &prefix_b
);
845 DCHECK(prefix_a
.database_id_
);
846 DCHECK(prefix_a
.object_store_id_
);
847 DCHECK_EQ(prefix_a
.index_id_
, ObjectStoreDataKey::kSpecialIndexNumber
);
848 DCHECK(prefix_b
.database_id_
);
849 DCHECK(prefix_b
.object_store_id_
);
850 DCHECK_EQ(prefix_b
.index_id_
, ObjectStoreDataKey::kSpecialIndexNumber
);
851 DCHECK(!slice_a
.empty());
852 DCHECK(!slice_b
.empty());
853 // Prefixes are not compared - it is assumed this was already done.
854 DCHECK(!prefix_a
.Compare(prefix_b
));
856 return CompareSuffix
<ObjectStoreDataKey
>(
857 &slice_a
, &slice_b
, only_compare_index_keys
, ok
);
861 int CompareSuffix
<IndexDataKey
>(StringPiece
* slice_a
,
862 StringPiece
* slice_b
,
863 bool only_compare_index_keys
,
866 int result
= CompareEncodedIDBKeys(slice_a
, slice_b
, ok
);
869 if (only_compare_index_keys
)
872 // sequence number [optional]
873 int64 sequence_number_a
= -1;
874 int64 sequence_number_b
= -1;
875 if (!slice_a
->empty() && !DecodeVarInt(slice_a
, &sequence_number_a
))
877 if (!slice_b
->empty() && !DecodeVarInt(slice_b
, &sequence_number_b
))
880 if (slice_a
->empty() || slice_b
->empty())
881 return CompareSizes(slice_a
->size(), slice_b
->size());
883 // primary key [optional]
884 result
= CompareEncodedIDBKeys(slice_a
, slice_b
, ok
);
888 return CompareInts(sequence_number_a
, sequence_number_b
);
892 int Compare
<IndexDataKey
>(const StringPiece
& a
,
893 const StringPiece
& b
,
894 bool only_compare_index_keys
,
898 StringPiece
slice_a(a
);
899 StringPiece
slice_b(b
);
900 bool ok_a
= KeyPrefix::Decode(&slice_a
, &prefix_a
);
901 bool ok_b
= KeyPrefix::Decode(&slice_b
, &prefix_b
);
904 DCHECK(prefix_a
.database_id_
);
905 DCHECK(prefix_a
.object_store_id_
);
906 DCHECK_GE(prefix_a
.index_id_
, kMinimumIndexId
);
907 DCHECK(prefix_b
.database_id_
);
908 DCHECK(prefix_b
.object_store_id_
);
909 DCHECK_GE(prefix_b
.index_id_
, kMinimumIndexId
);
910 DCHECK(!slice_a
.empty());
911 DCHECK(!slice_b
.empty());
912 // Prefixes are not compared - it is assumed this was already done.
913 DCHECK(!prefix_a
.Compare(prefix_b
));
915 return CompareSuffix
<IndexDataKey
>(
916 &slice_a
, &slice_b
, only_compare_index_keys
, ok
);
919 int Compare(const StringPiece
& a
,
920 const StringPiece
& b
,
921 bool only_compare_index_keys
,
923 StringPiece
slice_a(a
);
924 StringPiece
slice_b(b
);
927 bool ok_a
= KeyPrefix::Decode(&slice_a
, &prefix_a
);
928 bool ok_b
= KeyPrefix::Decode(&slice_b
, &prefix_b
);
931 if (!ok_a
|| !ok_b
) {
937 if (int x
= prefix_a
.Compare(prefix_b
))
940 switch (prefix_a
.type()) {
941 case KeyPrefix::GLOBAL_METADATA
: {
942 DCHECK(!slice_a
.empty());
943 DCHECK(!slice_b
.empty());
945 unsigned char type_byte_a
;
946 if (!DecodeByte(&slice_a
, &type_byte_a
)) {
951 unsigned char type_byte_b
;
952 if (!DecodeByte(&slice_b
, &type_byte_b
)) {
957 if (int x
= type_byte_a
- type_byte_b
)
959 if (type_byte_a
< kMaxSimpleGlobalMetaDataTypeByte
)
962 // Compare<> is used (which re-decodes the prefix) rather than an
963 // specialized CompareSuffix<> because metadata is relatively uncommon
966 if (type_byte_a
== kDatabaseFreeListTypeByte
)
967 return Compare
<DatabaseFreeListKey
>(
968 a
, b
, only_compare_index_keys
, ok
);
969 if (type_byte_a
== kDatabaseNameTypeByte
)
970 return Compare
<DatabaseNameKey
>(
971 a
, b
, /*only_compare_index_keys*/ false, ok
);
975 case KeyPrefix::DATABASE_METADATA
: {
976 DCHECK(!slice_a
.empty());
977 DCHECK(!slice_b
.empty());
979 unsigned char type_byte_a
;
980 if (!DecodeByte(&slice_a
, &type_byte_a
)) {
985 unsigned char type_byte_b
;
986 if (!DecodeByte(&slice_b
, &type_byte_b
)) {
991 if (int x
= type_byte_a
- type_byte_b
)
993 if (type_byte_a
< DatabaseMetaDataKey::MAX_SIMPLE_METADATA_TYPE
)
996 // Compare<> is used (which re-decodes the prefix) rather than an
997 // specialized CompareSuffix<> because metadata is relatively uncommon
1000 if (type_byte_a
== kObjectStoreMetaDataTypeByte
)
1001 return Compare
<ObjectStoreMetaDataKey
>(
1002 a
, b
, only_compare_index_keys
, ok
);
1003 if (type_byte_a
== kIndexMetaDataTypeByte
)
1004 return Compare
<IndexMetaDataKey
>(
1005 a
, b
, /*only_compare_index_keys*/ false, ok
);
1006 if (type_byte_a
== kObjectStoreFreeListTypeByte
)
1007 return Compare
<ObjectStoreFreeListKey
>(
1008 a
, b
, only_compare_index_keys
, ok
);
1009 if (type_byte_a
== kIndexFreeListTypeByte
)
1010 return Compare
<IndexFreeListKey
>(
1011 a
, b
, /*only_compare_index_keys*/ false, ok
);
1012 if (type_byte_a
== kObjectStoreNamesTypeByte
)
1013 return Compare
<ObjectStoreNamesKey
>(
1014 a
, b
, only_compare_index_keys
, ok
);
1015 if (type_byte_a
== kIndexNamesKeyTypeByte
)
1016 return Compare
<IndexNamesKey
>(
1017 a
, b
, /*only_compare_index_keys*/ false, ok
);
1021 case KeyPrefix::OBJECT_STORE_DATA
: {
1022 // Provide a stable ordering for invalid data.
1023 if (slice_a
.empty() || slice_b
.empty())
1024 return CompareSizes(slice_a
.size(), slice_b
.size());
1026 return CompareSuffix
<ObjectStoreDataKey
>(
1027 &slice_a
, &slice_b
, /*only_compare_index_keys*/ false, ok
);
1030 case KeyPrefix::EXISTS_ENTRY
: {
1031 // Provide a stable ordering for invalid data.
1032 if (slice_a
.empty() || slice_b
.empty())
1033 return CompareSizes(slice_a
.size(), slice_b
.size());
1035 return CompareSuffix
<ExistsEntryKey
>(
1036 &slice_a
, &slice_b
, /*only_compare_index_keys*/ false, ok
);
1039 case KeyPrefix::INDEX_DATA
: {
1040 // Provide a stable ordering for invalid data.
1041 if (slice_a
.empty() || slice_b
.empty())
1042 return CompareSizes(slice_a
.size(), slice_b
.size());
1044 return CompareSuffix
<IndexDataKey
>(
1045 &slice_a
, &slice_b
, only_compare_index_keys
, ok
);
1048 case KeyPrefix::INVALID_TYPE
:
1059 int Compare(const StringPiece
& a
,
1060 const StringPiece
& b
,
1061 bool only_compare_index_keys
) {
1063 int result
= Compare(a
, b
, only_compare_index_keys
, &ok
);
1070 KeyPrefix::KeyPrefix()
1071 : database_id_(INVALID_TYPE
),
1072 object_store_id_(INVALID_TYPE
),
1073 index_id_(INVALID_TYPE
) {}
1075 KeyPrefix::KeyPrefix(int64 database_id
)
1076 : database_id_(database_id
), object_store_id_(0), index_id_(0) {
1077 DCHECK(KeyPrefix::IsValidDatabaseId(database_id
));
1080 KeyPrefix::KeyPrefix(int64 database_id
, int64 object_store_id
)
1081 : database_id_(database_id
),
1082 object_store_id_(object_store_id
),
1084 DCHECK(KeyPrefix::IsValidDatabaseId(database_id
));
1085 DCHECK(KeyPrefix::IsValidObjectStoreId(object_store_id
));
1088 KeyPrefix::KeyPrefix(int64 database_id
, int64 object_store_id
, int64 index_id
)
1089 : database_id_(database_id
),
1090 object_store_id_(object_store_id
),
1091 index_id_(index_id
) {
1092 DCHECK(KeyPrefix::IsValidDatabaseId(database_id
));
1093 DCHECK(KeyPrefix::IsValidObjectStoreId(object_store_id
));
1094 DCHECK(KeyPrefix::IsValidIndexId(index_id
));
1097 KeyPrefix::KeyPrefix(enum Type type
,
1099 int64 object_store_id
,
1101 : database_id_(database_id
),
1102 object_store_id_(object_store_id
),
1103 index_id_(index_id
) {
1104 DCHECK_EQ(type
, INVALID_TYPE
);
1105 DCHECK(KeyPrefix::IsValidDatabaseId(database_id
));
1106 DCHECK(KeyPrefix::IsValidObjectStoreId(object_store_id
));
1109 KeyPrefix
KeyPrefix::CreateWithSpecialIndex(int64 database_id
,
1110 int64 object_store_id
,
1112 DCHECK(KeyPrefix::IsValidDatabaseId(database_id
));
1113 DCHECK(KeyPrefix::IsValidObjectStoreId(object_store_id
));
1115 return KeyPrefix(INVALID_TYPE
, database_id
, object_store_id
, index_id
);
1118 bool KeyPrefix::IsValidDatabaseId(int64 database_id
) {
1119 return (database_id
> 0) && (database_id
< KeyPrefix::kMaxDatabaseId
);
1122 bool KeyPrefix::IsValidObjectStoreId(int64 object_store_id
) {
1123 return (object_store_id
> 0) &&
1124 (object_store_id
< KeyPrefix::kMaxObjectStoreId
);
1127 bool KeyPrefix::IsValidIndexId(int64 index_id
) {
1128 return (index_id
>= kMinimumIndexId
) && (index_id
< KeyPrefix::kMaxIndexId
);
1131 bool KeyPrefix::Decode(StringPiece
* slice
, KeyPrefix
* result
) {
1132 unsigned char first_byte
;
1133 if (!DecodeByte(slice
, &first_byte
))
1136 size_t database_id_bytes
= ((first_byte
>> 5) & 0x7) + 1;
1137 size_t object_store_id_bytes
= ((first_byte
>> 2) & 0x7) + 1;
1138 size_t index_id_bytes
= (first_byte
& 0x3) + 1;
1140 if (database_id_bytes
+ object_store_id_bytes
+ index_id_bytes
>
1145 StringPiece
tmp(slice
->begin(), database_id_bytes
);
1146 if (!DecodeInt(&tmp
, &result
->database_id_
))
1149 slice
->remove_prefix(database_id_bytes
);
1151 StringPiece
tmp(slice
->begin(), object_store_id_bytes
);
1152 if (!DecodeInt(&tmp
, &result
->object_store_id_
))
1155 slice
->remove_prefix(object_store_id_bytes
);
1157 StringPiece
tmp(slice
->begin(), index_id_bytes
);
1158 if (!DecodeInt(&tmp
, &result
->index_id_
))
1161 slice
->remove_prefix(index_id_bytes
);
1165 std::string
KeyPrefix::EncodeEmpty() {
1166 const std::string
result(4, 0);
1167 DCHECK(EncodeInternal(0, 0, 0) == std::string(4, 0));
1171 std::string
KeyPrefix::Encode() const {
1172 DCHECK(database_id_
!= kInvalidId
);
1173 DCHECK(object_store_id_
!= kInvalidId
);
1174 DCHECK(index_id_
!= kInvalidId
);
1175 return EncodeInternal(database_id_
, object_store_id_
, index_id_
);
1178 std::string
KeyPrefix::EncodeInternal(int64 database_id
,
1179 int64 object_store_id
,
1181 std::string database_id_string
;
1182 std::string object_store_id_string
;
1183 std::string index_id_string
;
1185 EncodeIntSafely(database_id
, kMaxDatabaseId
, &database_id_string
);
1186 EncodeIntSafely(object_store_id
, kMaxObjectStoreId
, &object_store_id_string
);
1187 EncodeIntSafely(index_id
, kMaxIndexId
, &index_id_string
);
1189 DCHECK(database_id_string
.size() <= kMaxDatabaseIdSizeBytes
);
1190 DCHECK(object_store_id_string
.size() <= kMaxObjectStoreIdSizeBytes
);
1191 DCHECK(index_id_string
.size() <= kMaxIndexIdSizeBytes
);
1193 unsigned char first_byte
=
1194 (database_id_string
.size() - 1) << (kMaxObjectStoreIdSizeBits
+
1195 kMaxIndexIdSizeBits
) |
1196 (object_store_id_string
.size() - 1) << kMaxIndexIdSizeBits
|
1197 (index_id_string
.size() - 1);
1198 COMPILE_ASSERT(kMaxDatabaseIdSizeBits
+ kMaxObjectStoreIdSizeBits
+
1199 kMaxIndexIdSizeBits
==
1200 sizeof(first_byte
) * 8,
1203 ret
.reserve(kDefaultInlineBufferSize
);
1204 ret
.push_back(first_byte
);
1205 ret
.append(database_id_string
);
1206 ret
.append(object_store_id_string
);
1207 ret
.append(index_id_string
);
1209 DCHECK_LE(ret
.size(), kDefaultInlineBufferSize
);
1213 int KeyPrefix::Compare(const KeyPrefix
& other
) const {
1214 DCHECK(database_id_
!= kInvalidId
);
1215 DCHECK(object_store_id_
!= kInvalidId
);
1216 DCHECK(index_id_
!= kInvalidId
);
1218 if (database_id_
!= other
.database_id_
)
1219 return CompareInts(database_id_
, other
.database_id_
);
1220 if (object_store_id_
!= other
.object_store_id_
)
1221 return CompareInts(object_store_id_
, other
.object_store_id_
);
1222 if (index_id_
!= other
.index_id_
)
1223 return CompareInts(index_id_
, other
.index_id_
);
1227 KeyPrefix::Type
KeyPrefix::type() const {
1228 DCHECK(database_id_
!= kInvalidId
);
1229 DCHECK(object_store_id_
!= kInvalidId
);
1230 DCHECK(index_id_
!= kInvalidId
);
1233 return GLOBAL_METADATA
;
1234 if (!object_store_id_
)
1235 return DATABASE_METADATA
;
1236 if (index_id_
== kObjectStoreDataIndexId
)
1237 return OBJECT_STORE_DATA
;
1238 if (index_id_
== kExistsEntryIndexId
)
1239 return EXISTS_ENTRY
;
1240 if (index_id_
>= kMinimumIndexId
)
1244 return INVALID_TYPE
;
1247 std::string
SchemaVersionKey::Encode() {
1248 std::string ret
= KeyPrefix::EncodeEmpty();
1249 ret
.push_back(kSchemaVersionTypeByte
);
1253 std::string
MaxDatabaseIdKey::Encode() {
1254 std::string ret
= KeyPrefix::EncodeEmpty();
1255 ret
.push_back(kMaxDatabaseIdTypeByte
);
1259 std::string
DataVersionKey::Encode() {
1260 std::string ret
= KeyPrefix::EncodeEmpty();
1261 ret
.push_back(kDataVersionTypeByte
);
1265 DatabaseFreeListKey::DatabaseFreeListKey() : database_id_(-1) {}
1267 bool DatabaseFreeListKey::Decode(StringPiece
* slice
,
1268 DatabaseFreeListKey
* result
) {
1270 if (!KeyPrefix::Decode(slice
, &prefix
))
1272 DCHECK(!prefix
.database_id_
);
1273 DCHECK(!prefix
.object_store_id_
);
1274 DCHECK(!prefix
.index_id_
);
1275 unsigned char type_byte
= 0;
1276 if (!DecodeByte(slice
, &type_byte
))
1278 DCHECK_EQ(type_byte
, kDatabaseFreeListTypeByte
);
1279 if (!DecodeVarInt(slice
, &result
->database_id_
))
1284 std::string
DatabaseFreeListKey::Encode(int64 database_id
) {
1285 std::string ret
= KeyPrefix::EncodeEmpty();
1286 ret
.push_back(kDatabaseFreeListTypeByte
);
1287 EncodeVarInt(database_id
, &ret
);
1291 std::string
DatabaseFreeListKey::EncodeMaxKey() {
1292 return Encode(std::numeric_limits
<int64
>::max());
1295 int64
DatabaseFreeListKey::DatabaseId() const {
1296 DCHECK_GE(database_id_
, 0);
1297 return database_id_
;
1300 int DatabaseFreeListKey::Compare(const DatabaseFreeListKey
& other
) const {
1301 DCHECK_GE(database_id_
, 0);
1302 return CompareInts(database_id_
, other
.database_id_
);
1305 bool DatabaseNameKey::Decode(StringPiece
* slice
, DatabaseNameKey
* result
) {
1307 if (!KeyPrefix::Decode(slice
, &prefix
))
1309 DCHECK(!prefix
.database_id_
);
1310 DCHECK(!prefix
.object_store_id_
);
1311 DCHECK(!prefix
.index_id_
);
1312 unsigned char type_byte
= 0;
1313 if (!DecodeByte(slice
, &type_byte
))
1315 DCHECK_EQ(type_byte
, kDatabaseNameTypeByte
);
1316 if (!DecodeStringWithLength(slice
, &result
->origin_
))
1318 if (!DecodeStringWithLength(slice
, &result
->database_name_
))
1323 std::string
DatabaseNameKey::Encode(const std::string
& origin_identifier
,
1324 const string16
& database_name
) {
1325 std::string ret
= KeyPrefix::EncodeEmpty();
1326 ret
.push_back(kDatabaseNameTypeByte
);
1327 EncodeStringWithLength(base::ASCIIToUTF16(origin_identifier
), &ret
);
1328 EncodeStringWithLength(database_name
, &ret
);
1332 std::string
DatabaseNameKey::EncodeMinKeyForOrigin(
1333 const std::string
& origin_identifier
) {
1334 return Encode(origin_identifier
, string16());
1337 std::string
DatabaseNameKey::EncodeStopKeyForOrigin(
1338 const std::string
& origin_identifier
) {
1339 // just after origin in collation order
1340 return EncodeMinKeyForOrigin(origin_identifier
+ '\x01');
1343 int DatabaseNameKey::Compare(const DatabaseNameKey
& other
) {
1344 if (int x
= origin_
.compare(other
.origin_
))
1346 return database_name_
.compare(other
.database_name_
);
1349 std::string
DatabaseMetaDataKey::Encode(int64 database_id
,
1350 MetaDataType meta_data_type
) {
1351 KeyPrefix
prefix(database_id
);
1352 std::string ret
= prefix
.Encode();
1353 ret
.push_back(meta_data_type
);
1357 ObjectStoreMetaDataKey::ObjectStoreMetaDataKey()
1358 : object_store_id_(-1), meta_data_type_(-1) {}
1360 bool ObjectStoreMetaDataKey::Decode(StringPiece
* slice
,
1361 ObjectStoreMetaDataKey
* result
) {
1363 if (!KeyPrefix::Decode(slice
, &prefix
))
1365 DCHECK(prefix
.database_id_
);
1366 DCHECK(!prefix
.object_store_id_
);
1367 DCHECK(!prefix
.index_id_
);
1368 unsigned char type_byte
= 0;
1369 if (!DecodeByte(slice
, &type_byte
))
1371 DCHECK_EQ(type_byte
, kObjectStoreMetaDataTypeByte
);
1372 if (!DecodeVarInt(slice
, &result
->object_store_id_
))
1374 DCHECK(result
->object_store_id_
);
1375 if (!DecodeByte(slice
, &result
->meta_data_type_
))
1380 std::string
ObjectStoreMetaDataKey::Encode(int64 database_id
,
1381 int64 object_store_id
,
1382 unsigned char meta_data_type
) {
1383 KeyPrefix
prefix(database_id
);
1384 std::string ret
= prefix
.Encode();
1385 ret
.push_back(kObjectStoreMetaDataTypeByte
);
1386 EncodeVarInt(object_store_id
, &ret
);
1387 ret
.push_back(meta_data_type
);
1391 std::string
ObjectStoreMetaDataKey::EncodeMaxKey(int64 database_id
) {
1392 return Encode(database_id
,
1393 std::numeric_limits
<int64
>::max(),
1394 kObjectMetaDataTypeMaximum
);
1397 std::string
ObjectStoreMetaDataKey::EncodeMaxKey(int64 database_id
,
1398 int64 object_store_id
) {
1399 return Encode(database_id
, object_store_id
, kObjectMetaDataTypeMaximum
);
1402 int64
ObjectStoreMetaDataKey::ObjectStoreId() const {
1403 DCHECK_GE(object_store_id_
, 0);
1404 return object_store_id_
;
1406 unsigned char ObjectStoreMetaDataKey::MetaDataType() const {
1407 return meta_data_type_
;
1410 int ObjectStoreMetaDataKey::Compare(const ObjectStoreMetaDataKey
& other
) {
1411 DCHECK_GE(object_store_id_
, 0);
1412 if (int x
= CompareInts(object_store_id_
, other
.object_store_id_
))
1414 return meta_data_type_
- other
.meta_data_type_
;
1417 IndexMetaDataKey::IndexMetaDataKey()
1418 : object_store_id_(-1), index_id_(-1), meta_data_type_(0) {}
1420 bool IndexMetaDataKey::Decode(StringPiece
* slice
, IndexMetaDataKey
* result
) {
1422 if (!KeyPrefix::Decode(slice
, &prefix
))
1424 DCHECK(prefix
.database_id_
);
1425 DCHECK(!prefix
.object_store_id_
);
1426 DCHECK(!prefix
.index_id_
);
1427 unsigned char type_byte
= 0;
1428 if (!DecodeByte(slice
, &type_byte
))
1430 DCHECK_EQ(type_byte
, kIndexMetaDataTypeByte
);
1431 if (!DecodeVarInt(slice
, &result
->object_store_id_
))
1433 if (!DecodeVarInt(slice
, &result
->index_id_
))
1435 if (!DecodeByte(slice
, &result
->meta_data_type_
))
1440 std::string
IndexMetaDataKey::Encode(int64 database_id
,
1441 int64 object_store_id
,
1443 unsigned char meta_data_type
) {
1444 KeyPrefix
prefix(database_id
);
1445 std::string ret
= prefix
.Encode();
1446 ret
.push_back(kIndexMetaDataTypeByte
);
1447 EncodeVarInt(object_store_id
, &ret
);
1448 EncodeVarInt(index_id
, &ret
);
1449 EncodeByte(meta_data_type
, &ret
);
1453 std::string
IndexMetaDataKey::EncodeMaxKey(int64 database_id
,
1454 int64 object_store_id
) {
1455 return Encode(database_id
,
1457 std::numeric_limits
<int64
>::max(),
1458 kIndexMetaDataTypeMaximum
);
1461 std::string
IndexMetaDataKey::EncodeMaxKey(int64 database_id
,
1462 int64 object_store_id
,
1465 database_id
, object_store_id
, index_id
, kIndexMetaDataTypeMaximum
);
1468 int IndexMetaDataKey::Compare(const IndexMetaDataKey
& other
) {
1469 DCHECK_GE(object_store_id_
, 0);
1470 DCHECK_GE(index_id_
, 0);
1472 if (int x
= CompareInts(object_store_id_
, other
.object_store_id_
))
1474 if (int x
= CompareInts(index_id_
, other
.index_id_
))
1476 return meta_data_type_
- other
.meta_data_type_
;
1479 int64
IndexMetaDataKey::IndexId() const {
1480 DCHECK_GE(index_id_
, 0);
1484 ObjectStoreFreeListKey::ObjectStoreFreeListKey() : object_store_id_(-1) {}
1486 bool ObjectStoreFreeListKey::Decode(StringPiece
* slice
,
1487 ObjectStoreFreeListKey
* result
) {
1489 if (!KeyPrefix::Decode(slice
, &prefix
))
1491 DCHECK(prefix
.database_id_
);
1492 DCHECK(!prefix
.object_store_id_
);
1493 DCHECK(!prefix
.index_id_
);
1494 unsigned char type_byte
= 0;
1495 if (!DecodeByte(slice
, &type_byte
))
1497 DCHECK_EQ(type_byte
, kObjectStoreFreeListTypeByte
);
1498 if (!DecodeVarInt(slice
, &result
->object_store_id_
))
1503 std::string
ObjectStoreFreeListKey::Encode(int64 database_id
,
1504 int64 object_store_id
) {
1505 KeyPrefix
prefix(database_id
);
1506 std::string ret
= prefix
.Encode();
1507 ret
.push_back(kObjectStoreFreeListTypeByte
);
1508 EncodeVarInt(object_store_id
, &ret
);
1512 std::string
ObjectStoreFreeListKey::EncodeMaxKey(int64 database_id
) {
1513 return Encode(database_id
, std::numeric_limits
<int64
>::max());
1516 int64
ObjectStoreFreeListKey::ObjectStoreId() const {
1517 DCHECK_GE(object_store_id_
, 0);
1518 return object_store_id_
;
1521 int ObjectStoreFreeListKey::Compare(const ObjectStoreFreeListKey
& other
) {
1522 // TODO(jsbell): It may seem strange that we're not comparing database id's,
1523 // but that comparison will have been made earlier.
1524 // We should probably make this more clear, though...
1525 DCHECK_GE(object_store_id_
, 0);
1526 return CompareInts(object_store_id_
, other
.object_store_id_
);
1529 IndexFreeListKey::IndexFreeListKey() : object_store_id_(-1), index_id_(-1) {}
1531 bool IndexFreeListKey::Decode(StringPiece
* slice
, IndexFreeListKey
* result
) {
1533 if (!KeyPrefix::Decode(slice
, &prefix
))
1535 DCHECK(prefix
.database_id_
);
1536 DCHECK(!prefix
.object_store_id_
);
1537 DCHECK(!prefix
.index_id_
);
1538 unsigned char type_byte
= 0;
1539 if (!DecodeByte(slice
, &type_byte
))
1541 DCHECK_EQ(type_byte
, kIndexFreeListTypeByte
);
1542 if (!DecodeVarInt(slice
, &result
->object_store_id_
))
1544 if (!DecodeVarInt(slice
, &result
->index_id_
))
1549 std::string
IndexFreeListKey::Encode(int64 database_id
,
1550 int64 object_store_id
,
1552 KeyPrefix
prefix(database_id
);
1553 std::string ret
= prefix
.Encode();
1554 ret
.push_back(kIndexFreeListTypeByte
);
1555 EncodeVarInt(object_store_id
, &ret
);
1556 EncodeVarInt(index_id
, &ret
);
1560 std::string
IndexFreeListKey::EncodeMaxKey(int64 database_id
,
1561 int64 object_store_id
) {
1563 database_id
, object_store_id
, std::numeric_limits
<int64
>::max());
1566 int IndexFreeListKey::Compare(const IndexFreeListKey
& other
) {
1567 DCHECK_GE(object_store_id_
, 0);
1568 DCHECK_GE(index_id_
, 0);
1569 if (int x
= CompareInts(object_store_id_
, other
.object_store_id_
))
1571 return CompareInts(index_id_
, other
.index_id_
);
1574 int64
IndexFreeListKey::ObjectStoreId() const {
1575 DCHECK_GE(object_store_id_
, 0);
1576 return object_store_id_
;
1579 int64
IndexFreeListKey::IndexId() const {
1580 DCHECK_GE(index_id_
, 0);
1584 // TODO(jsbell): We never use this to look up object store ids,
1585 // because a mapping is kept in the IndexedDBDatabase. Can the
1586 // mapping become unreliable? Can we remove this?
1587 bool ObjectStoreNamesKey::Decode(StringPiece
* slice
,
1588 ObjectStoreNamesKey
* result
) {
1590 if (!KeyPrefix::Decode(slice
, &prefix
))
1592 DCHECK(prefix
.database_id_
);
1593 DCHECK(!prefix
.object_store_id_
);
1594 DCHECK(!prefix
.index_id_
);
1595 unsigned char type_byte
= 0;
1596 if (!DecodeByte(slice
, &type_byte
))
1598 DCHECK_EQ(type_byte
, kObjectStoreNamesTypeByte
);
1599 if (!DecodeStringWithLength(slice
, &result
->object_store_name_
))
1604 std::string
ObjectStoreNamesKey::Encode(int64 database_id
,
1605 const string16
& object_store_name
) {
1606 KeyPrefix
prefix(database_id
);
1607 std::string ret
= prefix
.Encode();
1608 ret
.push_back(kObjectStoreNamesTypeByte
);
1609 EncodeStringWithLength(object_store_name
, &ret
);
1613 int ObjectStoreNamesKey::Compare(const ObjectStoreNamesKey
& other
) {
1614 return object_store_name_
.compare(other
.object_store_name_
);
1617 IndexNamesKey::IndexNamesKey() : object_store_id_(-1) {}
1619 // TODO(jsbell): We never use this to look up index ids, because a mapping
1620 // is kept at a higher level.
1621 bool IndexNamesKey::Decode(StringPiece
* slice
, IndexNamesKey
* result
) {
1623 if (!KeyPrefix::Decode(slice
, &prefix
))
1625 DCHECK(prefix
.database_id_
);
1626 DCHECK(!prefix
.object_store_id_
);
1627 DCHECK(!prefix
.index_id_
);
1628 unsigned char type_byte
= 0;
1629 if (!DecodeByte(slice
, &type_byte
))
1631 DCHECK_EQ(type_byte
, kIndexNamesKeyTypeByte
);
1632 if (!DecodeVarInt(slice
, &result
->object_store_id_
))
1634 if (!DecodeStringWithLength(slice
, &result
->index_name_
))
1639 std::string
IndexNamesKey::Encode(int64 database_id
,
1640 int64 object_store_id
,
1641 const string16
& index_name
) {
1642 KeyPrefix
prefix(database_id
);
1643 std::string ret
= prefix
.Encode();
1644 ret
.push_back(kIndexNamesKeyTypeByte
);
1645 EncodeVarInt(object_store_id
, &ret
);
1646 EncodeStringWithLength(index_name
, &ret
);
1650 int IndexNamesKey::Compare(const IndexNamesKey
& other
) {
1651 DCHECK_GE(object_store_id_
, 0);
1652 if (int x
= CompareInts(object_store_id_
, other
.object_store_id_
))
1654 return index_name_
.compare(other
.index_name_
);
1657 ObjectStoreDataKey::ObjectStoreDataKey() {}
1658 ObjectStoreDataKey::~ObjectStoreDataKey() {}
1660 bool ObjectStoreDataKey::Decode(StringPiece
* slice
,
1661 ObjectStoreDataKey
* result
) {
1663 if (!KeyPrefix::Decode(slice
, &prefix
))
1665 DCHECK(prefix
.database_id_
);
1666 DCHECK(prefix
.object_store_id_
);
1667 DCHECK_EQ(prefix
.index_id_
, kSpecialIndexNumber
);
1668 if (!ExtractEncodedIDBKey(slice
, &result
->encoded_user_key_
))
1673 std::string
ObjectStoreDataKey::Encode(int64 database_id
,
1674 int64 object_store_id
,
1675 const std::string encoded_user_key
) {
1676 KeyPrefix
prefix(KeyPrefix::CreateWithSpecialIndex(
1677 database_id
, object_store_id
, kSpecialIndexNumber
));
1678 std::string ret
= prefix
.Encode();
1679 ret
.append(encoded_user_key
);
1684 std::string
ObjectStoreDataKey::Encode(int64 database_id
,
1685 int64 object_store_id
,
1686 const IndexedDBKey
& user_key
) {
1687 std::string encoded_key
;
1688 EncodeIDBKey(user_key
, &encoded_key
);
1689 return Encode(database_id
, object_store_id
, encoded_key
);
1692 int ObjectStoreDataKey::Compare(const ObjectStoreDataKey
& other
, bool* ok
) {
1693 return CompareEncodedIDBKeys(encoded_user_key_
, other
.encoded_user_key_
, ok
);
1696 scoped_ptr
<IndexedDBKey
> ObjectStoreDataKey::user_key() const {
1697 scoped_ptr
<IndexedDBKey
> key
;
1698 StringPiece
slice(encoded_user_key_
);
1699 if (!DecodeIDBKey(&slice
, &key
)) {
1700 // TODO(jsbell): Return error.
1705 const int64
ObjectStoreDataKey::kSpecialIndexNumber
= kObjectStoreDataIndexId
;
1707 ExistsEntryKey::ExistsEntryKey() {}
1708 ExistsEntryKey::~ExistsEntryKey() {}
1710 bool ExistsEntryKey::Decode(StringPiece
* slice
, ExistsEntryKey
* result
) {
1712 if (!KeyPrefix::Decode(slice
, &prefix
))
1714 DCHECK(prefix
.database_id_
);
1715 DCHECK(prefix
.object_store_id_
);
1716 DCHECK_EQ(prefix
.index_id_
, kSpecialIndexNumber
);
1717 if (!ExtractEncodedIDBKey(slice
, &result
->encoded_user_key_
))
1722 std::string
ExistsEntryKey::Encode(int64 database_id
,
1723 int64 object_store_id
,
1724 const std::string
& encoded_key
) {
1725 KeyPrefix
prefix(KeyPrefix::CreateWithSpecialIndex(
1726 database_id
, object_store_id
, kSpecialIndexNumber
));
1727 std::string ret
= prefix
.Encode();
1728 ret
.append(encoded_key
);
1732 std::string
ExistsEntryKey::Encode(int64 database_id
,
1733 int64 object_store_id
,
1734 const IndexedDBKey
& user_key
) {
1735 std::string encoded_key
;
1736 EncodeIDBKey(user_key
, &encoded_key
);
1737 return Encode(database_id
, object_store_id
, encoded_key
);
1740 int ExistsEntryKey::Compare(const ExistsEntryKey
& other
, bool* ok
) {
1741 return CompareEncodedIDBKeys(encoded_user_key_
, other
.encoded_user_key_
, ok
);
1744 scoped_ptr
<IndexedDBKey
> ExistsEntryKey::user_key() const {
1745 scoped_ptr
<IndexedDBKey
> key
;
1746 StringPiece
slice(encoded_user_key_
);
1747 if (!DecodeIDBKey(&slice
, &key
)) {
1748 // TODO(jsbell): Return error.
1753 const int64
ExistsEntryKey::kSpecialIndexNumber
= kExistsEntryIndexId
;
1755 IndexDataKey::IndexDataKey()
1757 object_store_id_(-1),
1759 sequence_number_(-1) {}
1761 IndexDataKey::~IndexDataKey() {}
1763 bool IndexDataKey::Decode(StringPiece
* slice
, IndexDataKey
* result
) {
1765 if (!KeyPrefix::Decode(slice
, &prefix
))
1767 DCHECK(prefix
.database_id_
);
1768 DCHECK(prefix
.object_store_id_
);
1769 DCHECK_GE(prefix
.index_id_
, kMinimumIndexId
);
1770 result
->database_id_
= prefix
.database_id_
;
1771 result
->object_store_id_
= prefix
.object_store_id_
;
1772 result
->index_id_
= prefix
.index_id_
;
1773 result
->sequence_number_
= -1;
1774 result
->encoded_primary_key_
= MinIDBKey();
1776 if (!ExtractEncodedIDBKey(slice
, &result
->encoded_user_key_
))
1779 // [optional] sequence number
1782 if (!DecodeVarInt(slice
, &result
->sequence_number_
))
1785 // [optional] primary key
1788 if (!ExtractEncodedIDBKey(slice
, &result
->encoded_primary_key_
))
1793 std::string
IndexDataKey::Encode(int64 database_id
,
1794 int64 object_store_id
,
1796 const std::string
& encoded_user_key
,
1797 const std::string
& encoded_primary_key
,
1798 int64 sequence_number
) {
1799 KeyPrefix
prefix(database_id
, object_store_id
, index_id
);
1800 std::string ret
= prefix
.Encode();
1801 ret
.append(encoded_user_key
);
1802 EncodeVarInt(sequence_number
, &ret
);
1803 ret
.append(encoded_primary_key
);
1807 std::string
IndexDataKey::Encode(int64 database_id
,
1808 int64 object_store_id
,
1810 const IndexedDBKey
& user_key
) {
1811 std::string encoded_key
;
1812 EncodeIDBKey(user_key
, &encoded_key
);
1814 database_id
, object_store_id
, index_id
, encoded_key
, MinIDBKey(), 0);
1817 std::string
IndexDataKey::EncodeMinKey(int64 database_id
,
1818 int64 object_store_id
,
1821 database_id
, object_store_id
, index_id
, MinIDBKey(), MinIDBKey(), 0);
1824 std::string
IndexDataKey::EncodeMaxKey(int64 database_id
,
1825 int64 object_store_id
,
1827 return Encode(database_id
,
1832 std::numeric_limits
<int64
>::max());
1835 int IndexDataKey::Compare(const IndexDataKey
& other
,
1836 bool only_compare_index_keys
,
1838 DCHECK_GE(database_id_
, 0);
1839 DCHECK_GE(object_store_id_
, 0);
1840 DCHECK_GE(index_id_
, 0);
1842 CompareEncodedIDBKeys(encoded_user_key_
, other
.encoded_user_key_
, ok
);
1845 if (only_compare_index_keys
)
1847 result
= CompareEncodedIDBKeys(
1848 encoded_primary_key_
, other
.encoded_primary_key_
, ok
);
1851 return CompareInts(sequence_number_
, other
.sequence_number_
);
1854 int64
IndexDataKey::DatabaseId() const {
1855 DCHECK_GE(database_id_
, 0);
1856 return database_id_
;
1859 int64
IndexDataKey::ObjectStoreId() const {
1860 DCHECK_GE(object_store_id_
, 0);
1861 return object_store_id_
;
1864 int64
IndexDataKey::IndexId() const {
1865 DCHECK_GE(index_id_
, 0);
1869 scoped_ptr
<IndexedDBKey
> IndexDataKey::user_key() const {
1870 scoped_ptr
<IndexedDBKey
> key
;
1871 StringPiece
slice(encoded_user_key_
);
1872 if (!DecodeIDBKey(&slice
, &key
)) {
1873 // TODO(jsbell): Return error.
1878 scoped_ptr
<IndexedDBKey
> IndexDataKey::primary_key() const {
1879 scoped_ptr
<IndexedDBKey
> key
;
1880 StringPiece
slice(encoded_primary_key_
);
1881 if (!DecodeIDBKey(&slice
, &key
)) {
1882 // TODO(jsbell): Return error.
1887 } // namespace content