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 blink::WebIDBKeyType
;
151 using blink::WebIDBKeyTypeArray
;
152 using blink::WebIDBKeyTypeBinary
;
153 using blink::WebIDBKeyTypeDate
;
154 using blink::WebIDBKeyTypeInvalid
;
155 using blink::WebIDBKeyTypeMin
;
156 using blink::WebIDBKeyTypeNull
;
157 using blink::WebIDBKeyTypeNumber
;
158 using blink::WebIDBKeyTypeString
;
159 using blink::WebIDBKeyPathType
;
160 using blink::WebIDBKeyPathTypeArray
;
161 using blink::WebIDBKeyPathTypeNull
;
162 using blink::WebIDBKeyPathTypeString
;
166 // As most of the IndexedDBKeys and encoded values are short, we
167 // initialize some Vectors with a default inline buffer size to reduce
168 // the memory re-allocations when the Vectors are appended.
169 static const size_t kDefaultInlineBufferSize
= 32;
171 static const unsigned char kIndexedDBKeyNullTypeByte
= 0;
172 static const unsigned char kIndexedDBKeyStringTypeByte
= 1;
173 static const unsigned char kIndexedDBKeyDateTypeByte
= 2;
174 static const unsigned char kIndexedDBKeyNumberTypeByte
= 3;
175 static const unsigned char kIndexedDBKeyArrayTypeByte
= 4;
176 static const unsigned char kIndexedDBKeyMinKeyTypeByte
= 5;
177 static const unsigned char kIndexedDBKeyBinaryTypeByte
= 6;
179 static const unsigned char kIndexedDBKeyPathTypeCodedByte1
= 0;
180 static const unsigned char kIndexedDBKeyPathTypeCodedByte2
= 0;
182 static const unsigned char kObjectStoreDataIndexId
= 1;
183 static const unsigned char kExistsEntryIndexId
= 2;
185 static const unsigned char kSchemaVersionTypeByte
= 0;
186 static const unsigned char kMaxDatabaseIdTypeByte
= 1;
187 static const unsigned char kDataVersionTypeByte
= 2;
188 static const unsigned char kMaxSimpleGlobalMetaDataTypeByte
=
189 3; // Insert before this and increment.
190 static const unsigned char kDatabaseFreeListTypeByte
= 100;
191 static const unsigned char kDatabaseNameTypeByte
= 201;
193 static const unsigned char kObjectStoreMetaDataTypeByte
= 50;
194 static const unsigned char kIndexMetaDataTypeByte
= 100;
195 static const unsigned char kObjectStoreFreeListTypeByte
= 150;
196 static const unsigned char kIndexFreeListTypeByte
= 151;
197 static const unsigned char kObjectStoreNamesTypeByte
= 200;
198 static const unsigned char kIndexNamesKeyTypeByte
= 201;
200 static const unsigned char kObjectMetaDataTypeMaximum
= 255;
201 static const unsigned char kIndexMetaDataTypeMaximum
= 255;
203 const unsigned char kMinimumIndexId
= 30;
205 inline void EncodeIntSafely(int64 nParam
, int64 max
, std::string
* into
) {
206 DCHECK_LE(nParam
, max
);
207 return EncodeInt(nParam
, into
);
210 std::string
MaxIDBKey() {
212 EncodeByte(kIndexedDBKeyNullTypeByte
, &ret
);
216 std::string
MinIDBKey() {
218 EncodeByte(kIndexedDBKeyMinKeyTypeByte
, &ret
);
222 void EncodeByte(unsigned char value
, std::string
* into
) {
223 into
->push_back(value
);
226 void EncodeBool(bool value
, std::string
* into
) {
227 into
->push_back(value
? 1 : 0);
230 void EncodeInt(int64 value
, std::string
* into
) {
232 // Exercised by unit tests in debug only.
235 uint64 n
= static_cast<uint64
>(value
);
244 void EncodeVarInt(int64 value
, std::string
* into
) {
246 // Exercised by unit tests in debug only.
249 uint64 n
= static_cast<uint64
>(value
);
252 unsigned char c
= n
& 0x7f;
260 void EncodeString(const base::string16
& value
, std::string
* into
) {
263 // Backing store is UTF-16BE, convert from host endianness.
264 size_t length
= value
.length();
265 size_t current
= into
->size();
266 into
->resize(into
->size() + length
* sizeof(base::char16
));
268 const base::char16
* src
= value
.c_str();
270 reinterpret_cast<base::char16
*>(&*into
->begin() + current
);
271 for (unsigned i
= 0; i
< length
; ++i
)
272 *dst
++ = htons(*src
++);
275 void EncodeBinary(const std::string
& value
, std::string
* into
) {
276 EncodeVarInt(value
.length(), into
);
277 into
->append(value
.begin(), value
.end());
278 DCHECK(into
->size() >= value
.size());
281 void EncodeStringWithLength(const base::string16
& value
, std::string
* into
) {
282 EncodeVarInt(value
.length(), into
);
283 EncodeString(value
, into
);
286 void EncodeDouble(double value
, std::string
* into
) {
287 // This always has host endianness.
288 const char* p
= reinterpret_cast<char*>(&value
);
289 into
->insert(into
->end(), p
, p
+ sizeof(value
));
292 void EncodeIDBKey(const IndexedDBKey
& value
, std::string
* into
) {
293 size_t previous_size
= into
->size();
294 DCHECK(value
.IsValid());
295 switch (value
.type()) {
296 case WebIDBKeyTypeNull
:
297 case WebIDBKeyTypeInvalid
:
298 case WebIDBKeyTypeMin
:
301 EncodeByte(kIndexedDBKeyNullTypeByte
, into
);
304 case WebIDBKeyTypeArray
: {
305 EncodeByte(kIndexedDBKeyArrayTypeByte
, into
);
306 size_t length
= value
.array().size();
307 EncodeVarInt(length
, into
);
308 for (size_t i
= 0; i
< length
; ++i
)
309 EncodeIDBKey(value
.array()[i
], into
);
310 DCHECK_GT(into
->size(), previous_size
);
313 case WebIDBKeyTypeBinary
: {
314 EncodeByte(kIndexedDBKeyBinaryTypeByte
, into
);
315 EncodeBinary(value
.binary(), into
);
316 DCHECK_GT(into
->size(), previous_size
);
319 case WebIDBKeyTypeString
: {
320 EncodeByte(kIndexedDBKeyStringTypeByte
, into
);
321 EncodeStringWithLength(value
.string(), into
);
322 DCHECK_GT(into
->size(), previous_size
);
325 case WebIDBKeyTypeDate
: {
326 EncodeByte(kIndexedDBKeyDateTypeByte
, into
);
327 EncodeDouble(value
.date(), into
);
328 DCHECK_EQ(9u, static_cast<size_t>(into
->size() - previous_size
));
331 case WebIDBKeyTypeNumber
: {
332 EncodeByte(kIndexedDBKeyNumberTypeByte
, into
);
333 EncodeDouble(value
.number(), into
);
334 DCHECK_EQ(9u, static_cast<size_t>(into
->size() - previous_size
));
342 void EncodeIDBKeyPath(const IndexedDBKeyPath
& value
, std::string
* into
) {
343 // May be typed, or may be a raw string. An invalid leading
344 // byte is used to identify typed coding. New records are
345 // always written as typed.
346 EncodeByte(kIndexedDBKeyPathTypeCodedByte1
, into
);
347 EncodeByte(kIndexedDBKeyPathTypeCodedByte2
, into
);
348 EncodeByte(static_cast<char>(value
.type()), into
);
349 switch (value
.type()) {
350 case WebIDBKeyPathTypeNull
:
352 case WebIDBKeyPathTypeString
: {
353 EncodeStringWithLength(value
.string(), into
);
356 case WebIDBKeyPathTypeArray
: {
357 const std::vector
<base::string16
>& array
= value
.array();
358 size_t count
= array
.size();
359 EncodeVarInt(count
, into
);
360 for (size_t i
= 0; i
< count
; ++i
) {
361 EncodeStringWithLength(array
[i
], into
);
368 bool DecodeByte(StringPiece
* slice
, unsigned char* value
) {
372 *value
= (*slice
)[0];
373 slice
->remove_prefix(1);
377 bool DecodeBool(StringPiece
* slice
, bool* value
) {
381 *value
= !!(*slice
)[0];
382 slice
->remove_prefix(1);
386 bool DecodeInt(StringPiece
* slice
, int64
* value
) {
390 StringPiece::const_iterator it
= slice
->begin();
393 while (it
!= slice
->end()) {
394 unsigned char c
= *it
++;
395 ret
|= static_cast<int64
>(c
) << shift
;
399 slice
->remove_prefix(it
- slice
->begin());
403 bool DecodeVarInt(StringPiece
* slice
, int64
* value
) {
407 StringPiece::const_iterator it
= slice
->begin();
411 if (it
== slice
->end())
414 unsigned char c
= *it
;
415 ret
|= static_cast<int64
>(c
& 0x7f) << shift
;
417 } while (*it
++ & 0x80);
419 slice
->remove_prefix(it
- slice
->begin());
423 bool DecodeString(StringPiece
* slice
, base::string16
* value
) {
424 if (slice
->empty()) {
429 // Backing store is UTF-16BE, convert to host endianness.
430 DCHECK(!(slice
->size() % sizeof(base::char16
)));
431 size_t length
= slice
->size() / sizeof(base::char16
);
432 base::string16 decoded
;
433 decoded
.reserve(length
);
434 const base::char16
* encoded
=
435 reinterpret_cast<const base::char16
*>(slice
->begin());
436 for (unsigned i
= 0; i
< length
; ++i
)
437 decoded
.push_back(ntohs(*encoded
++));
440 slice
->remove_prefix(length
* sizeof(base::char16
));
444 bool DecodeStringWithLength(StringPiece
* slice
, base::string16
* value
) {
449 if (!DecodeVarInt(slice
, &length
) || length
< 0)
451 size_t bytes
= length
* sizeof(base::char16
);
452 if (slice
->size() < bytes
)
455 StringPiece
subpiece(slice
->begin(), bytes
);
456 slice
->remove_prefix(bytes
);
457 if (!DecodeString(&subpiece
, value
))
463 bool DecodeBinary(StringPiece
* slice
, std::string
* value
) {
468 if (!DecodeVarInt(slice
, &length
) || length
< 0)
470 size_t size
= length
;
471 if (slice
->size() < size
)
474 value
->assign(slice
->begin(), size
);
475 slice
->remove_prefix(size
);
479 bool DecodeIDBKey(StringPiece
* slice
, scoped_ptr
<IndexedDBKey
>* value
) {
483 unsigned char type
= (*slice
)[0];
484 slice
->remove_prefix(1);
487 case kIndexedDBKeyNullTypeByte
:
488 *value
= make_scoped_ptr(new IndexedDBKey());
491 case kIndexedDBKeyArrayTypeByte
: {
493 if (!DecodeVarInt(slice
, &length
) || length
< 0)
495 IndexedDBKey::KeyArray array
;
497 scoped_ptr
<IndexedDBKey
> key
;
498 if (!DecodeIDBKey(slice
, &key
))
500 array
.push_back(*key
);
502 *value
= make_scoped_ptr(new IndexedDBKey(array
));
505 case kIndexedDBKeyBinaryTypeByte
: {
507 if (!DecodeBinary(slice
, &binary
))
509 *value
= make_scoped_ptr(new IndexedDBKey(binary
));
512 case kIndexedDBKeyStringTypeByte
: {
514 if (!DecodeStringWithLength(slice
, &s
))
516 *value
= make_scoped_ptr(new IndexedDBKey(s
));
519 case kIndexedDBKeyDateTypeByte
: {
521 if (!DecodeDouble(slice
, &d
))
523 *value
= make_scoped_ptr(new IndexedDBKey(d
, WebIDBKeyTypeDate
));
526 case kIndexedDBKeyNumberTypeByte
: {
528 if (!DecodeDouble(slice
, &d
))
530 *value
= make_scoped_ptr(new IndexedDBKey(d
, WebIDBKeyTypeNumber
));
539 bool DecodeDouble(StringPiece
* slice
, double* value
) {
540 if (slice
->size() < sizeof(*value
))
543 memcpy(value
, slice
->begin(), sizeof(*value
));
544 slice
->remove_prefix(sizeof(*value
));
548 bool DecodeIDBKeyPath(StringPiece
* slice
, IndexedDBKeyPath
* value
) {
549 // May be typed, or may be a raw string. An invalid leading
550 // byte sequence is used to identify typed coding. New records are
551 // always written as typed.
552 if (slice
->size() < 3 || (*slice
)[0] != kIndexedDBKeyPathTypeCodedByte1
||
553 (*slice
)[1] != kIndexedDBKeyPathTypeCodedByte2
) {
555 if (!DecodeString(slice
, &s
))
557 *value
= IndexedDBKeyPath(s
);
561 slice
->remove_prefix(2);
562 DCHECK(!slice
->empty());
563 WebIDBKeyPathType type
= static_cast<WebIDBKeyPathType
>((*slice
)[0]);
564 slice
->remove_prefix(1);
567 case WebIDBKeyPathTypeNull
:
568 DCHECK(slice
->empty());
569 *value
= IndexedDBKeyPath();
571 case WebIDBKeyPathTypeString
: {
572 base::string16 string
;
573 if (!DecodeStringWithLength(slice
, &string
))
575 DCHECK(slice
->empty());
576 *value
= IndexedDBKeyPath(string
);
579 case WebIDBKeyPathTypeArray
: {
580 std::vector
<base::string16
> array
;
582 if (!DecodeVarInt(slice
, &count
))
586 base::string16 string
;
587 if (!DecodeStringWithLength(slice
, &string
))
589 array
.push_back(string
);
591 DCHECK(slice
->empty());
592 *value
= IndexedDBKeyPath(array
);
600 bool ConsumeEncodedIDBKey(StringPiece
* slice
) {
601 unsigned char type
= (*slice
)[0];
602 slice
->remove_prefix(1);
605 case kIndexedDBKeyNullTypeByte
:
606 case kIndexedDBKeyMinKeyTypeByte
:
608 case kIndexedDBKeyArrayTypeByte
: {
610 if (!DecodeVarInt(slice
, &length
))
613 if (!ConsumeEncodedIDBKey(slice
))
618 case kIndexedDBKeyBinaryTypeByte
: {
620 if (!DecodeVarInt(slice
, &length
) || length
< 0)
622 if (slice
->size() < static_cast<size_t>(length
))
624 slice
->remove_prefix(length
);
627 case kIndexedDBKeyStringTypeByte
: {
629 if (!DecodeVarInt(slice
, &length
) || length
< 0)
631 if (slice
->size() < static_cast<size_t>(length
) * sizeof(base::char16
))
633 slice
->remove_prefix(length
* sizeof(base::char16
));
636 case kIndexedDBKeyDateTypeByte
:
637 case kIndexedDBKeyNumberTypeByte
:
638 if (slice
->size() < sizeof(double))
640 slice
->remove_prefix(sizeof(double));
647 bool ExtractEncodedIDBKey(StringPiece
* slice
, std::string
* result
) {
648 const char* start
= slice
->begin();
649 if (!ConsumeEncodedIDBKey(slice
))
653 result
->assign(start
, slice
->begin());
657 static WebIDBKeyType
KeyTypeByteToKeyType(unsigned char type
) {
659 case kIndexedDBKeyNullTypeByte
:
660 return WebIDBKeyTypeInvalid
;
661 case kIndexedDBKeyArrayTypeByte
:
662 return WebIDBKeyTypeArray
;
663 case kIndexedDBKeyBinaryTypeByte
:
664 return WebIDBKeyTypeBinary
;
665 case kIndexedDBKeyStringTypeByte
:
666 return WebIDBKeyTypeString
;
667 case kIndexedDBKeyDateTypeByte
:
668 return WebIDBKeyTypeDate
;
669 case kIndexedDBKeyNumberTypeByte
:
670 return WebIDBKeyTypeNumber
;
671 case kIndexedDBKeyMinKeyTypeByte
:
672 return WebIDBKeyTypeMin
;
676 return WebIDBKeyTypeInvalid
;
679 int CompareEncodedStringsWithLength(StringPiece
* slice1
,
683 if (!DecodeVarInt(slice1
, &len1
) || !DecodeVarInt(slice2
, &len2
)) {
689 if (len1
< 0 || len2
< 0) {
693 DCHECK_GE(slice1
->size(), len1
* sizeof(base::char16
));
694 DCHECK_GE(slice2
->size(), len2
* sizeof(base::char16
));
695 if (slice1
->size() < len1
* sizeof(base::char16
) ||
696 slice2
->size() < len2
* sizeof(base::char16
)) {
701 // Extract the string data, and advance the passed slices.
702 StringPiece
string1(slice1
->begin(), len1
* sizeof(base::char16
));
703 StringPiece
string2(slice2
->begin(), len2
* sizeof(base::char16
));
704 slice1
->remove_prefix(len1
* sizeof(base::char16
));
705 slice2
->remove_prefix(len2
* sizeof(base::char16
));
708 // Strings are UTF-16BE encoded, so a simple memcmp is sufficient.
709 return string1
.compare(string2
);
712 int CompareEncodedBinary(StringPiece
* slice1
,
716 if (!DecodeVarInt(slice1
, &len1
) || !DecodeVarInt(slice2
, &len2
)) {
722 if (len1
< 0 || len2
< 0) {
729 DCHECK_GE(slice1
->size(), size1
);
730 DCHECK_GE(slice2
->size(), size2
);
731 if (slice1
->size() < size1
|| slice2
->size() < size2
) {
736 // Extract the binary data, and advance the passed slices.
737 StringPiece
binary1(slice1
->begin(), size1
);
738 StringPiece
binary2(slice2
->begin(), size2
);
739 slice1
->remove_prefix(size1
);
740 slice2
->remove_prefix(size2
);
743 // This is the same as a memcmp()
744 return binary1
.compare(binary2
);
747 static int CompareInts(int64 a
, int64 b
) {
749 // Exercised by unit tests in debug only.
761 static inline int CompareSizes(size_t a
, size_t b
) {
769 static int CompareTypes(WebIDBKeyType a
, WebIDBKeyType b
) { return b
- a
; }
771 int CompareEncodedIDBKeys(StringPiece
* slice_a
,
772 StringPiece
* slice_b
,
774 DCHECK(!slice_a
->empty());
775 DCHECK(!slice_b
->empty());
777 unsigned char type_a
= (*slice_a
)[0];
778 unsigned char type_b
= (*slice_b
)[0];
779 slice_a
->remove_prefix(1);
780 slice_b
->remove_prefix(1);
782 if (int x
= CompareTypes(KeyTypeByteToKeyType(type_a
),
783 KeyTypeByteToKeyType(type_b
)))
787 case kIndexedDBKeyNullTypeByte
:
788 case kIndexedDBKeyMinKeyTypeByte
:
789 // Null type or max type; no payload to compare.
791 case kIndexedDBKeyArrayTypeByte
: {
792 int64 length_a
, length_b
;
793 if (!DecodeVarInt(slice_a
, &length_a
) ||
794 !DecodeVarInt(slice_b
, &length_b
)) {
798 for (int64 i
= 0; i
< length_a
&& i
< length_b
; ++i
) {
799 int result
= CompareEncodedIDBKeys(slice_a
, slice_b
, ok
);
803 return length_a
- length_b
;
805 case kIndexedDBKeyBinaryTypeByte
:
806 return CompareEncodedBinary(slice_a
, slice_b
, ok
);
807 case kIndexedDBKeyStringTypeByte
:
808 return CompareEncodedStringsWithLength(slice_a
, slice_b
, ok
);
809 case kIndexedDBKeyDateTypeByte
:
810 case kIndexedDBKeyNumberTypeByte
: {
812 if (!DecodeDouble(slice_a
, &d
) || !DecodeDouble(slice_b
, &e
)) {
830 template <typename KeyType
>
831 int Compare(const StringPiece
& a
,
832 const StringPiece
& b
,
833 bool only_compare_index_keys
,
838 StringPiece
slice_a(a
);
839 if (!KeyType::Decode(&slice_a
, &key_a
)) {
843 StringPiece
slice_b(b
);
844 if (!KeyType::Decode(&slice_b
, &key_b
)) {
850 return key_a
.Compare(key_b
);
853 template <typename KeyType
>
854 int CompareSuffix(StringPiece
* a
,
856 bool only_compare_index_keys
,
863 int CompareSuffix
<ExistsEntryKey
>(StringPiece
* slice_a
,
864 StringPiece
* slice_b
,
865 bool only_compare_index_keys
,
867 DCHECK(!slice_a
->empty());
868 DCHECK(!slice_b
->empty());
869 return CompareEncodedIDBKeys(slice_a
, slice_b
, ok
);
873 int CompareSuffix
<ObjectStoreDataKey
>(StringPiece
* slice_a
,
874 StringPiece
* slice_b
,
875 bool only_compare_index_keys
,
877 return CompareEncodedIDBKeys(slice_a
, slice_b
, ok
);
881 int CompareSuffix
<IndexDataKey
>(StringPiece
* slice_a
,
882 StringPiece
* slice_b
,
883 bool only_compare_index_keys
,
886 int result
= CompareEncodedIDBKeys(slice_a
, slice_b
, ok
);
889 if (only_compare_index_keys
)
892 // sequence number [optional]
893 int64 sequence_number_a
= -1;
894 int64 sequence_number_b
= -1;
895 if (!slice_a
->empty() && !DecodeVarInt(slice_a
, &sequence_number_a
))
897 if (!slice_b
->empty() && !DecodeVarInt(slice_b
, &sequence_number_b
))
900 if (slice_a
->empty() || slice_b
->empty())
901 return CompareSizes(slice_a
->size(), slice_b
->size());
903 // primary key [optional]
904 result
= CompareEncodedIDBKeys(slice_a
, slice_b
, ok
);
908 return CompareInts(sequence_number_a
, sequence_number_b
);
911 int Compare(const StringPiece
& a
,
912 const StringPiece
& b
,
913 bool only_compare_index_keys
,
915 StringPiece
slice_a(a
);
916 StringPiece
slice_b(b
);
919 bool ok_a
= KeyPrefix::Decode(&slice_a
, &prefix_a
);
920 bool ok_b
= KeyPrefix::Decode(&slice_b
, &prefix_b
);
923 if (!ok_a
|| !ok_b
) {
929 if (int x
= prefix_a
.Compare(prefix_b
))
932 switch (prefix_a
.type()) {
933 case KeyPrefix::GLOBAL_METADATA
: {
934 DCHECK(!slice_a
.empty());
935 DCHECK(!slice_b
.empty());
937 unsigned char type_byte_a
;
938 if (!DecodeByte(&slice_a
, &type_byte_a
)) {
943 unsigned char type_byte_b
;
944 if (!DecodeByte(&slice_b
, &type_byte_b
)) {
949 if (int x
= type_byte_a
- type_byte_b
)
951 if (type_byte_a
< kMaxSimpleGlobalMetaDataTypeByte
)
954 // Compare<> is used (which re-decodes the prefix) rather than an
955 // specialized CompareSuffix<> because metadata is relatively uncommon
958 if (type_byte_a
== kDatabaseFreeListTypeByte
) {
959 // TODO(jsbell): No need to pass only_compare_index_keys through here.
960 return Compare
<DatabaseFreeListKey
>(a
, b
, only_compare_index_keys
, ok
);
962 if (type_byte_a
== kDatabaseNameTypeByte
) {
963 return Compare
<DatabaseNameKey
>(
964 a
, b
, /*only_compare_index_keys*/ false, ok
);
969 case KeyPrefix::DATABASE_METADATA
: {
970 DCHECK(!slice_a
.empty());
971 DCHECK(!slice_b
.empty());
973 unsigned char type_byte_a
;
974 if (!DecodeByte(&slice_a
, &type_byte_a
)) {
979 unsigned char type_byte_b
;
980 if (!DecodeByte(&slice_b
, &type_byte_b
)) {
985 if (int x
= type_byte_a
- type_byte_b
)
987 if (type_byte_a
< DatabaseMetaDataKey::MAX_SIMPLE_METADATA_TYPE
)
990 // Compare<> is used (which re-decodes the prefix) rather than an
991 // specialized CompareSuffix<> because metadata is relatively uncommon
994 if (type_byte_a
== kObjectStoreMetaDataTypeByte
) {
995 // TODO(jsbell): No need to pass only_compare_index_keys through here.
996 return Compare
<ObjectStoreMetaDataKey
>(
997 a
, b
, only_compare_index_keys
, ok
);
999 if (type_byte_a
== kIndexMetaDataTypeByte
) {
1000 return Compare
<IndexMetaDataKey
>(
1001 a
, b
, /*only_compare_index_keys*/ false, ok
);
1003 if (type_byte_a
== kObjectStoreFreeListTypeByte
) {
1004 return Compare
<ObjectStoreFreeListKey
>(
1005 a
, b
, only_compare_index_keys
, ok
);
1007 if (type_byte_a
== kIndexFreeListTypeByte
) {
1008 return Compare
<IndexFreeListKey
>(
1009 a
, b
, /*only_compare_index_keys*/ false, ok
);
1011 if (type_byte_a
== kObjectStoreNamesTypeByte
) {
1012 // TODO(jsbell): No need to pass only_compare_index_keys through here.
1013 return Compare
<ObjectStoreNamesKey
>(
1014 a
, b
, only_compare_index_keys
, ok
);
1016 if (type_byte_a
== kIndexNamesKeyTypeByte
) {
1017 return Compare
<IndexNamesKey
>(
1018 a
, b
, /*only_compare_index_keys*/ false, ok
);
1023 case KeyPrefix::OBJECT_STORE_DATA
: {
1024 // Provide a stable ordering for invalid data.
1025 if (slice_a
.empty() || slice_b
.empty())
1026 return CompareSizes(slice_a
.size(), slice_b
.size());
1028 return CompareSuffix
<ObjectStoreDataKey
>(
1029 &slice_a
, &slice_b
, /*only_compare_index_keys*/ false, ok
);
1032 case KeyPrefix::EXISTS_ENTRY
: {
1033 // Provide a stable ordering for invalid data.
1034 if (slice_a
.empty() || slice_b
.empty())
1035 return CompareSizes(slice_a
.size(), slice_b
.size());
1037 return CompareSuffix
<ExistsEntryKey
>(
1038 &slice_a
, &slice_b
, /*only_compare_index_keys*/ false, ok
);
1041 case KeyPrefix::INDEX_DATA
: {
1042 // Provide a stable ordering for invalid data.
1043 if (slice_a
.empty() || slice_b
.empty())
1044 return CompareSizes(slice_a
.size(), slice_b
.size());
1046 return CompareSuffix
<IndexDataKey
>(
1047 &slice_a
, &slice_b
, only_compare_index_keys
, ok
);
1050 case KeyPrefix::INVALID_TYPE
:
1061 int Compare(const StringPiece
& a
,
1062 const StringPiece
& b
,
1063 bool only_compare_index_keys
) {
1065 int result
= Compare(a
, b
, only_compare_index_keys
, &ok
);
1072 KeyPrefix::KeyPrefix()
1073 : database_id_(INVALID_TYPE
),
1074 object_store_id_(INVALID_TYPE
),
1075 index_id_(INVALID_TYPE
) {}
1077 KeyPrefix::KeyPrefix(int64 database_id
)
1078 : database_id_(database_id
), object_store_id_(0), index_id_(0) {
1079 DCHECK(KeyPrefix::IsValidDatabaseId(database_id
));
1082 KeyPrefix::KeyPrefix(int64 database_id
, int64 object_store_id
)
1083 : database_id_(database_id
),
1084 object_store_id_(object_store_id
),
1086 DCHECK(KeyPrefix::IsValidDatabaseId(database_id
));
1087 DCHECK(KeyPrefix::IsValidObjectStoreId(object_store_id
));
1090 KeyPrefix::KeyPrefix(int64 database_id
, int64 object_store_id
, int64 index_id
)
1091 : database_id_(database_id
),
1092 object_store_id_(object_store_id
),
1093 index_id_(index_id
) {
1094 DCHECK(KeyPrefix::IsValidDatabaseId(database_id
));
1095 DCHECK(KeyPrefix::IsValidObjectStoreId(object_store_id
));
1096 DCHECK(KeyPrefix::IsValidIndexId(index_id
));
1099 KeyPrefix::KeyPrefix(enum Type type
,
1101 int64 object_store_id
,
1103 : database_id_(database_id
),
1104 object_store_id_(object_store_id
),
1105 index_id_(index_id
) {
1106 DCHECK_EQ(type
, INVALID_TYPE
);
1107 DCHECK(KeyPrefix::IsValidDatabaseId(database_id
));
1108 DCHECK(KeyPrefix::IsValidObjectStoreId(object_store_id
));
1111 KeyPrefix
KeyPrefix::CreateWithSpecialIndex(int64 database_id
,
1112 int64 object_store_id
,
1114 DCHECK(KeyPrefix::IsValidDatabaseId(database_id
));
1115 DCHECK(KeyPrefix::IsValidObjectStoreId(object_store_id
));
1117 return KeyPrefix(INVALID_TYPE
, database_id
, object_store_id
, index_id
);
1120 bool KeyPrefix::IsValidDatabaseId(int64 database_id
) {
1121 return (database_id
> 0) && (database_id
< KeyPrefix::kMaxDatabaseId
);
1124 bool KeyPrefix::IsValidObjectStoreId(int64 object_store_id
) {
1125 return (object_store_id
> 0) &&
1126 (object_store_id
< KeyPrefix::kMaxObjectStoreId
);
1129 bool KeyPrefix::IsValidIndexId(int64 index_id
) {
1130 return (index_id
>= kMinimumIndexId
) && (index_id
< KeyPrefix::kMaxIndexId
);
1133 bool KeyPrefix::Decode(StringPiece
* slice
, KeyPrefix
* result
) {
1134 unsigned char first_byte
;
1135 if (!DecodeByte(slice
, &first_byte
))
1138 size_t database_id_bytes
= ((first_byte
>> 5) & 0x7) + 1;
1139 size_t object_store_id_bytes
= ((first_byte
>> 2) & 0x7) + 1;
1140 size_t index_id_bytes
= (first_byte
& 0x3) + 1;
1142 if (database_id_bytes
+ object_store_id_bytes
+ index_id_bytes
>
1147 StringPiece
tmp(slice
->begin(), database_id_bytes
);
1148 if (!DecodeInt(&tmp
, &result
->database_id_
))
1151 slice
->remove_prefix(database_id_bytes
);
1153 StringPiece
tmp(slice
->begin(), object_store_id_bytes
);
1154 if (!DecodeInt(&tmp
, &result
->object_store_id_
))
1157 slice
->remove_prefix(object_store_id_bytes
);
1159 StringPiece
tmp(slice
->begin(), index_id_bytes
);
1160 if (!DecodeInt(&tmp
, &result
->index_id_
))
1163 slice
->remove_prefix(index_id_bytes
);
1167 std::string
KeyPrefix::EncodeEmpty() {
1168 const std::string
result(4, 0);
1169 DCHECK(EncodeInternal(0, 0, 0) == std::string(4, 0));
1173 std::string
KeyPrefix::Encode() const {
1174 DCHECK(database_id_
!= kInvalidId
);
1175 DCHECK(object_store_id_
!= kInvalidId
);
1176 DCHECK(index_id_
!= kInvalidId
);
1177 return EncodeInternal(database_id_
, object_store_id_
, index_id_
);
1180 std::string
KeyPrefix::EncodeInternal(int64 database_id
,
1181 int64 object_store_id
,
1183 std::string database_id_string
;
1184 std::string object_store_id_string
;
1185 std::string index_id_string
;
1187 EncodeIntSafely(database_id
, kMaxDatabaseId
, &database_id_string
);
1188 EncodeIntSafely(object_store_id
, kMaxObjectStoreId
, &object_store_id_string
);
1189 EncodeIntSafely(index_id
, kMaxIndexId
, &index_id_string
);
1191 DCHECK(database_id_string
.size() <= kMaxDatabaseIdSizeBytes
);
1192 DCHECK(object_store_id_string
.size() <= kMaxObjectStoreIdSizeBytes
);
1193 DCHECK(index_id_string
.size() <= kMaxIndexIdSizeBytes
);
1195 unsigned char first_byte
=
1196 (database_id_string
.size() - 1) << (kMaxObjectStoreIdSizeBits
+
1197 kMaxIndexIdSizeBits
) |
1198 (object_store_id_string
.size() - 1) << kMaxIndexIdSizeBits
|
1199 (index_id_string
.size() - 1);
1200 COMPILE_ASSERT(kMaxDatabaseIdSizeBits
+ kMaxObjectStoreIdSizeBits
+
1201 kMaxIndexIdSizeBits
==
1202 sizeof(first_byte
) * 8,
1205 ret
.reserve(kDefaultInlineBufferSize
);
1206 ret
.push_back(first_byte
);
1207 ret
.append(database_id_string
);
1208 ret
.append(object_store_id_string
);
1209 ret
.append(index_id_string
);
1211 DCHECK_LE(ret
.size(), kDefaultInlineBufferSize
);
1215 int KeyPrefix::Compare(const KeyPrefix
& other
) const {
1216 DCHECK(database_id_
!= kInvalidId
);
1217 DCHECK(object_store_id_
!= kInvalidId
);
1218 DCHECK(index_id_
!= kInvalidId
);
1220 if (database_id_
!= other
.database_id_
)
1221 return CompareInts(database_id_
, other
.database_id_
);
1222 if (object_store_id_
!= other
.object_store_id_
)
1223 return CompareInts(object_store_id_
, other
.object_store_id_
);
1224 if (index_id_
!= other
.index_id_
)
1225 return CompareInts(index_id_
, other
.index_id_
);
1229 KeyPrefix::Type
KeyPrefix::type() const {
1230 DCHECK(database_id_
!= kInvalidId
);
1231 DCHECK(object_store_id_
!= kInvalidId
);
1232 DCHECK(index_id_
!= kInvalidId
);
1235 return GLOBAL_METADATA
;
1236 if (!object_store_id_
)
1237 return DATABASE_METADATA
;
1238 if (index_id_
== kObjectStoreDataIndexId
)
1239 return OBJECT_STORE_DATA
;
1240 if (index_id_
== kExistsEntryIndexId
)
1241 return EXISTS_ENTRY
;
1242 if (index_id_
>= kMinimumIndexId
)
1246 return INVALID_TYPE
;
1249 std::string
SchemaVersionKey::Encode() {
1250 std::string ret
= KeyPrefix::EncodeEmpty();
1251 ret
.push_back(kSchemaVersionTypeByte
);
1255 std::string
MaxDatabaseIdKey::Encode() {
1256 std::string ret
= KeyPrefix::EncodeEmpty();
1257 ret
.push_back(kMaxDatabaseIdTypeByte
);
1261 std::string
DataVersionKey::Encode() {
1262 std::string ret
= KeyPrefix::EncodeEmpty();
1263 ret
.push_back(kDataVersionTypeByte
);
1267 DatabaseFreeListKey::DatabaseFreeListKey() : database_id_(-1) {}
1269 bool DatabaseFreeListKey::Decode(StringPiece
* slice
,
1270 DatabaseFreeListKey
* result
) {
1272 if (!KeyPrefix::Decode(slice
, &prefix
))
1274 DCHECK(!prefix
.database_id_
);
1275 DCHECK(!prefix
.object_store_id_
);
1276 DCHECK(!prefix
.index_id_
);
1277 unsigned char type_byte
= 0;
1278 if (!DecodeByte(slice
, &type_byte
))
1280 DCHECK_EQ(type_byte
, kDatabaseFreeListTypeByte
);
1281 if (!DecodeVarInt(slice
, &result
->database_id_
))
1286 std::string
DatabaseFreeListKey::Encode(int64 database_id
) {
1287 std::string ret
= KeyPrefix::EncodeEmpty();
1288 ret
.push_back(kDatabaseFreeListTypeByte
);
1289 EncodeVarInt(database_id
, &ret
);
1293 std::string
DatabaseFreeListKey::EncodeMaxKey() {
1294 return Encode(std::numeric_limits
<int64
>::max());
1297 int64
DatabaseFreeListKey::DatabaseId() const {
1298 DCHECK_GE(database_id_
, 0);
1299 return database_id_
;
1302 int DatabaseFreeListKey::Compare(const DatabaseFreeListKey
& other
) const {
1303 DCHECK_GE(database_id_
, 0);
1304 return CompareInts(database_id_
, other
.database_id_
);
1307 bool DatabaseNameKey::Decode(StringPiece
* slice
, DatabaseNameKey
* result
) {
1309 if (!KeyPrefix::Decode(slice
, &prefix
))
1311 DCHECK(!prefix
.database_id_
);
1312 DCHECK(!prefix
.object_store_id_
);
1313 DCHECK(!prefix
.index_id_
);
1314 unsigned char type_byte
= 0;
1315 if (!DecodeByte(slice
, &type_byte
))
1317 DCHECK_EQ(type_byte
, kDatabaseNameTypeByte
);
1318 if (!DecodeStringWithLength(slice
, &result
->origin_
))
1320 if (!DecodeStringWithLength(slice
, &result
->database_name_
))
1325 std::string
DatabaseNameKey::Encode(const std::string
& origin_identifier
,
1326 const base::string16
& database_name
) {
1327 std::string ret
= KeyPrefix::EncodeEmpty();
1328 ret
.push_back(kDatabaseNameTypeByte
);
1329 EncodeStringWithLength(base::ASCIIToUTF16(origin_identifier
), &ret
);
1330 EncodeStringWithLength(database_name
, &ret
);
1334 std::string
DatabaseNameKey::EncodeMinKeyForOrigin(
1335 const std::string
& origin_identifier
) {
1336 return Encode(origin_identifier
, base::string16());
1339 std::string
DatabaseNameKey::EncodeStopKeyForOrigin(
1340 const std::string
& origin_identifier
) {
1341 // just after origin in collation order
1342 return EncodeMinKeyForOrigin(origin_identifier
+ '\x01');
1345 int DatabaseNameKey::Compare(const DatabaseNameKey
& other
) {
1346 if (int x
= origin_
.compare(other
.origin_
))
1348 return database_name_
.compare(other
.database_name_
);
1351 std::string
DatabaseMetaDataKey::Encode(int64 database_id
,
1352 MetaDataType meta_data_type
) {
1353 KeyPrefix
prefix(database_id
);
1354 std::string ret
= prefix
.Encode();
1355 ret
.push_back(meta_data_type
);
1359 ObjectStoreMetaDataKey::ObjectStoreMetaDataKey()
1360 : object_store_id_(-1), meta_data_type_(-1) {}
1362 bool ObjectStoreMetaDataKey::Decode(StringPiece
* slice
,
1363 ObjectStoreMetaDataKey
* result
) {
1365 if (!KeyPrefix::Decode(slice
, &prefix
))
1367 DCHECK(prefix
.database_id_
);
1368 DCHECK(!prefix
.object_store_id_
);
1369 DCHECK(!prefix
.index_id_
);
1370 unsigned char type_byte
= 0;
1371 if (!DecodeByte(slice
, &type_byte
))
1373 DCHECK_EQ(type_byte
, kObjectStoreMetaDataTypeByte
);
1374 if (!DecodeVarInt(slice
, &result
->object_store_id_
))
1376 DCHECK(result
->object_store_id_
);
1377 if (!DecodeByte(slice
, &result
->meta_data_type_
))
1382 std::string
ObjectStoreMetaDataKey::Encode(int64 database_id
,
1383 int64 object_store_id
,
1384 unsigned char meta_data_type
) {
1385 KeyPrefix
prefix(database_id
);
1386 std::string ret
= prefix
.Encode();
1387 ret
.push_back(kObjectStoreMetaDataTypeByte
);
1388 EncodeVarInt(object_store_id
, &ret
);
1389 ret
.push_back(meta_data_type
);
1393 std::string
ObjectStoreMetaDataKey::EncodeMaxKey(int64 database_id
) {
1394 return Encode(database_id
,
1395 std::numeric_limits
<int64
>::max(),
1396 kObjectMetaDataTypeMaximum
);
1399 std::string
ObjectStoreMetaDataKey::EncodeMaxKey(int64 database_id
,
1400 int64 object_store_id
) {
1401 return Encode(database_id
, object_store_id
, kObjectMetaDataTypeMaximum
);
1404 int64
ObjectStoreMetaDataKey::ObjectStoreId() const {
1405 DCHECK_GE(object_store_id_
, 0);
1406 return object_store_id_
;
1408 unsigned char ObjectStoreMetaDataKey::MetaDataType() const {
1409 return meta_data_type_
;
1412 int ObjectStoreMetaDataKey::Compare(const ObjectStoreMetaDataKey
& other
) {
1413 DCHECK_GE(object_store_id_
, 0);
1414 if (int x
= CompareInts(object_store_id_
, other
.object_store_id_
))
1416 return meta_data_type_
- other
.meta_data_type_
;
1419 IndexMetaDataKey::IndexMetaDataKey()
1420 : object_store_id_(-1), index_id_(-1), meta_data_type_(0) {}
1422 bool IndexMetaDataKey::Decode(StringPiece
* slice
, IndexMetaDataKey
* result
) {
1424 if (!KeyPrefix::Decode(slice
, &prefix
))
1426 DCHECK(prefix
.database_id_
);
1427 DCHECK(!prefix
.object_store_id_
);
1428 DCHECK(!prefix
.index_id_
);
1429 unsigned char type_byte
= 0;
1430 if (!DecodeByte(slice
, &type_byte
))
1432 DCHECK_EQ(type_byte
, kIndexMetaDataTypeByte
);
1433 if (!DecodeVarInt(slice
, &result
->object_store_id_
))
1435 if (!DecodeVarInt(slice
, &result
->index_id_
))
1437 if (!DecodeByte(slice
, &result
->meta_data_type_
))
1442 std::string
IndexMetaDataKey::Encode(int64 database_id
,
1443 int64 object_store_id
,
1445 unsigned char meta_data_type
) {
1446 KeyPrefix
prefix(database_id
);
1447 std::string ret
= prefix
.Encode();
1448 ret
.push_back(kIndexMetaDataTypeByte
);
1449 EncodeVarInt(object_store_id
, &ret
);
1450 EncodeVarInt(index_id
, &ret
);
1451 EncodeByte(meta_data_type
, &ret
);
1455 std::string
IndexMetaDataKey::EncodeMaxKey(int64 database_id
,
1456 int64 object_store_id
) {
1457 return Encode(database_id
,
1459 std::numeric_limits
<int64
>::max(),
1460 kIndexMetaDataTypeMaximum
);
1463 std::string
IndexMetaDataKey::EncodeMaxKey(int64 database_id
,
1464 int64 object_store_id
,
1467 database_id
, object_store_id
, index_id
, kIndexMetaDataTypeMaximum
);
1470 int IndexMetaDataKey::Compare(const IndexMetaDataKey
& other
) {
1471 DCHECK_GE(object_store_id_
, 0);
1472 DCHECK_GE(index_id_
, 0);
1474 if (int x
= CompareInts(object_store_id_
, other
.object_store_id_
))
1476 if (int x
= CompareInts(index_id_
, other
.index_id_
))
1478 return meta_data_type_
- other
.meta_data_type_
;
1481 int64
IndexMetaDataKey::IndexId() const {
1482 DCHECK_GE(index_id_
, 0);
1486 ObjectStoreFreeListKey::ObjectStoreFreeListKey() : object_store_id_(-1) {}
1488 bool ObjectStoreFreeListKey::Decode(StringPiece
* slice
,
1489 ObjectStoreFreeListKey
* result
) {
1491 if (!KeyPrefix::Decode(slice
, &prefix
))
1493 DCHECK(prefix
.database_id_
);
1494 DCHECK(!prefix
.object_store_id_
);
1495 DCHECK(!prefix
.index_id_
);
1496 unsigned char type_byte
= 0;
1497 if (!DecodeByte(slice
, &type_byte
))
1499 DCHECK_EQ(type_byte
, kObjectStoreFreeListTypeByte
);
1500 if (!DecodeVarInt(slice
, &result
->object_store_id_
))
1505 std::string
ObjectStoreFreeListKey::Encode(int64 database_id
,
1506 int64 object_store_id
) {
1507 KeyPrefix
prefix(database_id
);
1508 std::string ret
= prefix
.Encode();
1509 ret
.push_back(kObjectStoreFreeListTypeByte
);
1510 EncodeVarInt(object_store_id
, &ret
);
1514 std::string
ObjectStoreFreeListKey::EncodeMaxKey(int64 database_id
) {
1515 return Encode(database_id
, std::numeric_limits
<int64
>::max());
1518 int64
ObjectStoreFreeListKey::ObjectStoreId() const {
1519 DCHECK_GE(object_store_id_
, 0);
1520 return object_store_id_
;
1523 int ObjectStoreFreeListKey::Compare(const ObjectStoreFreeListKey
& other
) {
1524 // TODO(jsbell): It may seem strange that we're not comparing database id's,
1525 // but that comparison will have been made earlier.
1526 // We should probably make this more clear, though...
1527 DCHECK_GE(object_store_id_
, 0);
1528 return CompareInts(object_store_id_
, other
.object_store_id_
);
1531 IndexFreeListKey::IndexFreeListKey() : object_store_id_(-1), index_id_(-1) {}
1533 bool IndexFreeListKey::Decode(StringPiece
* slice
, IndexFreeListKey
* result
) {
1535 if (!KeyPrefix::Decode(slice
, &prefix
))
1537 DCHECK(prefix
.database_id_
);
1538 DCHECK(!prefix
.object_store_id_
);
1539 DCHECK(!prefix
.index_id_
);
1540 unsigned char type_byte
= 0;
1541 if (!DecodeByte(slice
, &type_byte
))
1543 DCHECK_EQ(type_byte
, kIndexFreeListTypeByte
);
1544 if (!DecodeVarInt(slice
, &result
->object_store_id_
))
1546 if (!DecodeVarInt(slice
, &result
->index_id_
))
1551 std::string
IndexFreeListKey::Encode(int64 database_id
,
1552 int64 object_store_id
,
1554 KeyPrefix
prefix(database_id
);
1555 std::string ret
= prefix
.Encode();
1556 ret
.push_back(kIndexFreeListTypeByte
);
1557 EncodeVarInt(object_store_id
, &ret
);
1558 EncodeVarInt(index_id
, &ret
);
1562 std::string
IndexFreeListKey::EncodeMaxKey(int64 database_id
,
1563 int64 object_store_id
) {
1565 database_id
, object_store_id
, std::numeric_limits
<int64
>::max());
1568 int IndexFreeListKey::Compare(const IndexFreeListKey
& other
) {
1569 DCHECK_GE(object_store_id_
, 0);
1570 DCHECK_GE(index_id_
, 0);
1571 if (int x
= CompareInts(object_store_id_
, other
.object_store_id_
))
1573 return CompareInts(index_id_
, other
.index_id_
);
1576 int64
IndexFreeListKey::ObjectStoreId() const {
1577 DCHECK_GE(object_store_id_
, 0);
1578 return object_store_id_
;
1581 int64
IndexFreeListKey::IndexId() const {
1582 DCHECK_GE(index_id_
, 0);
1586 // TODO(jsbell): We never use this to look up object store ids,
1587 // because a mapping is kept in the IndexedDBDatabase. Can the
1588 // mapping become unreliable? Can we remove this?
1589 bool ObjectStoreNamesKey::Decode(StringPiece
* slice
,
1590 ObjectStoreNamesKey
* result
) {
1592 if (!KeyPrefix::Decode(slice
, &prefix
))
1594 DCHECK(prefix
.database_id_
);
1595 DCHECK(!prefix
.object_store_id_
);
1596 DCHECK(!prefix
.index_id_
);
1597 unsigned char type_byte
= 0;
1598 if (!DecodeByte(slice
, &type_byte
))
1600 DCHECK_EQ(type_byte
, kObjectStoreNamesTypeByte
);
1601 if (!DecodeStringWithLength(slice
, &result
->object_store_name_
))
1606 std::string
ObjectStoreNamesKey::Encode(
1608 const base::string16
& object_store_name
) {
1609 KeyPrefix
prefix(database_id
);
1610 std::string ret
= prefix
.Encode();
1611 ret
.push_back(kObjectStoreNamesTypeByte
);
1612 EncodeStringWithLength(object_store_name
, &ret
);
1616 int ObjectStoreNamesKey::Compare(const ObjectStoreNamesKey
& other
) {
1617 return object_store_name_
.compare(other
.object_store_name_
);
1620 IndexNamesKey::IndexNamesKey() : object_store_id_(-1) {}
1622 // TODO(jsbell): We never use this to look up index ids, because a mapping
1623 // is kept at a higher level.
1624 bool IndexNamesKey::Decode(StringPiece
* slice
, IndexNamesKey
* result
) {
1626 if (!KeyPrefix::Decode(slice
, &prefix
))
1628 DCHECK(prefix
.database_id_
);
1629 DCHECK(!prefix
.object_store_id_
);
1630 DCHECK(!prefix
.index_id_
);
1631 unsigned char type_byte
= 0;
1632 if (!DecodeByte(slice
, &type_byte
))
1634 DCHECK_EQ(type_byte
, kIndexNamesKeyTypeByte
);
1635 if (!DecodeVarInt(slice
, &result
->object_store_id_
))
1637 if (!DecodeStringWithLength(slice
, &result
->index_name_
))
1642 std::string
IndexNamesKey::Encode(int64 database_id
,
1643 int64 object_store_id
,
1644 const base::string16
& index_name
) {
1645 KeyPrefix
prefix(database_id
);
1646 std::string ret
= prefix
.Encode();
1647 ret
.push_back(kIndexNamesKeyTypeByte
);
1648 EncodeVarInt(object_store_id
, &ret
);
1649 EncodeStringWithLength(index_name
, &ret
);
1653 int IndexNamesKey::Compare(const IndexNamesKey
& other
) {
1654 DCHECK_GE(object_store_id_
, 0);
1655 if (int x
= CompareInts(object_store_id_
, other
.object_store_id_
))
1657 return index_name_
.compare(other
.index_name_
);
1660 ObjectStoreDataKey::ObjectStoreDataKey() {}
1661 ObjectStoreDataKey::~ObjectStoreDataKey() {}
1663 bool ObjectStoreDataKey::Decode(StringPiece
* slice
,
1664 ObjectStoreDataKey
* result
) {
1666 if (!KeyPrefix::Decode(slice
, &prefix
))
1668 DCHECK(prefix
.database_id_
);
1669 DCHECK(prefix
.object_store_id_
);
1670 DCHECK_EQ(prefix
.index_id_
, kSpecialIndexNumber
);
1671 if (!ExtractEncodedIDBKey(slice
, &result
->encoded_user_key_
))
1676 std::string
ObjectStoreDataKey::Encode(int64 database_id
,
1677 int64 object_store_id
,
1678 const std::string encoded_user_key
) {
1679 KeyPrefix
prefix(KeyPrefix::CreateWithSpecialIndex(
1680 database_id
, object_store_id
, kSpecialIndexNumber
));
1681 std::string ret
= prefix
.Encode();
1682 ret
.append(encoded_user_key
);
1687 std::string
ObjectStoreDataKey::Encode(int64 database_id
,
1688 int64 object_store_id
,
1689 const IndexedDBKey
& user_key
) {
1690 std::string encoded_key
;
1691 EncodeIDBKey(user_key
, &encoded_key
);
1692 return Encode(database_id
, object_store_id
, encoded_key
);
1695 scoped_ptr
<IndexedDBKey
> ObjectStoreDataKey::user_key() const {
1696 scoped_ptr
<IndexedDBKey
> key
;
1697 StringPiece
slice(encoded_user_key_
);
1698 if (!DecodeIDBKey(&slice
, &key
)) {
1699 // TODO(jsbell): Return error.
1704 const int64
ObjectStoreDataKey::kSpecialIndexNumber
= kObjectStoreDataIndexId
;
1706 ExistsEntryKey::ExistsEntryKey() {}
1707 ExistsEntryKey::~ExistsEntryKey() {}
1709 bool ExistsEntryKey::Decode(StringPiece
* slice
, ExistsEntryKey
* result
) {
1711 if (!KeyPrefix::Decode(slice
, &prefix
))
1713 DCHECK(prefix
.database_id_
);
1714 DCHECK(prefix
.object_store_id_
);
1715 DCHECK_EQ(prefix
.index_id_
, kSpecialIndexNumber
);
1716 if (!ExtractEncodedIDBKey(slice
, &result
->encoded_user_key_
))
1721 std::string
ExistsEntryKey::Encode(int64 database_id
,
1722 int64 object_store_id
,
1723 const std::string
& encoded_key
) {
1724 KeyPrefix
prefix(KeyPrefix::CreateWithSpecialIndex(
1725 database_id
, object_store_id
, kSpecialIndexNumber
));
1726 std::string ret
= prefix
.Encode();
1727 ret
.append(encoded_key
);
1731 std::string
ExistsEntryKey::Encode(int64 database_id
,
1732 int64 object_store_id
,
1733 const IndexedDBKey
& user_key
) {
1734 std::string encoded_key
;
1735 EncodeIDBKey(user_key
, &encoded_key
);
1736 return Encode(database_id
, object_store_id
, encoded_key
);
1739 scoped_ptr
<IndexedDBKey
> ExistsEntryKey::user_key() const {
1740 scoped_ptr
<IndexedDBKey
> key
;
1741 StringPiece
slice(encoded_user_key_
);
1742 if (!DecodeIDBKey(&slice
, &key
)) {
1743 // TODO(jsbell): Return error.
1748 const int64
ExistsEntryKey::kSpecialIndexNumber
= kExistsEntryIndexId
;
1750 IndexDataKey::IndexDataKey()
1752 object_store_id_(-1),
1754 sequence_number_(-1) {}
1756 IndexDataKey::~IndexDataKey() {}
1758 bool IndexDataKey::Decode(StringPiece
* slice
, IndexDataKey
* result
) {
1760 if (!KeyPrefix::Decode(slice
, &prefix
))
1762 DCHECK(prefix
.database_id_
);
1763 DCHECK(prefix
.object_store_id_
);
1764 DCHECK_GE(prefix
.index_id_
, kMinimumIndexId
);
1765 result
->database_id_
= prefix
.database_id_
;
1766 result
->object_store_id_
= prefix
.object_store_id_
;
1767 result
->index_id_
= prefix
.index_id_
;
1768 result
->sequence_number_
= -1;
1769 result
->encoded_primary_key_
= MinIDBKey();
1771 if (!ExtractEncodedIDBKey(slice
, &result
->encoded_user_key_
))
1774 // [optional] sequence number
1777 if (!DecodeVarInt(slice
, &result
->sequence_number_
))
1780 // [optional] primary key
1783 if (!ExtractEncodedIDBKey(slice
, &result
->encoded_primary_key_
))
1788 std::string
IndexDataKey::Encode(int64 database_id
,
1789 int64 object_store_id
,
1791 const std::string
& encoded_user_key
,
1792 const std::string
& encoded_primary_key
,
1793 int64 sequence_number
) {
1794 KeyPrefix
prefix(database_id
, object_store_id
, index_id
);
1795 std::string ret
= prefix
.Encode();
1796 ret
.append(encoded_user_key
);
1797 EncodeVarInt(sequence_number
, &ret
);
1798 ret
.append(encoded_primary_key
);
1802 std::string
IndexDataKey::Encode(int64 database_id
,
1803 int64 object_store_id
,
1805 const IndexedDBKey
& user_key
) {
1806 std::string encoded_key
;
1807 EncodeIDBKey(user_key
, &encoded_key
);
1809 database_id
, object_store_id
, index_id
, encoded_key
, MinIDBKey(), 0);
1812 std::string
IndexDataKey::Encode(int64 database_id
,
1813 int64 object_store_id
,
1815 const IndexedDBKey
& user_key
,
1816 const IndexedDBKey
& user_primary_key
) {
1817 std::string encoded_key
;
1818 EncodeIDBKey(user_key
, &encoded_key
);
1819 std::string encoded_primary_key
;
1820 EncodeIDBKey(user_primary_key
, &encoded_primary_key
);
1821 return Encode(database_id
,
1825 encoded_primary_key
,
1829 std::string
IndexDataKey::EncodeMinKey(int64 database_id
,
1830 int64 object_store_id
,
1833 database_id
, object_store_id
, index_id
, MinIDBKey(), MinIDBKey(), 0);
1836 std::string
IndexDataKey::EncodeMaxKey(int64 database_id
,
1837 int64 object_store_id
,
1839 return Encode(database_id
,
1844 std::numeric_limits
<int64
>::max());
1847 int64
IndexDataKey::DatabaseId() const {
1848 DCHECK_GE(database_id_
, 0);
1849 return database_id_
;
1852 int64
IndexDataKey::ObjectStoreId() const {
1853 DCHECK_GE(object_store_id_
, 0);
1854 return object_store_id_
;
1857 int64
IndexDataKey::IndexId() const {
1858 DCHECK_GE(index_id_
, 0);
1862 scoped_ptr
<IndexedDBKey
> IndexDataKey::user_key() const {
1863 scoped_ptr
<IndexedDBKey
> key
;
1864 StringPiece
slice(encoded_user_key_
);
1865 if (!DecodeIDBKey(&slice
, &key
)) {
1866 // TODO(jsbell): Return error.
1871 scoped_ptr
<IndexedDBKey
> IndexDataKey::primary_key() const {
1872 scoped_ptr
<IndexedDBKey
> key
;
1873 StringPiece
slice(encoded_primary_key_
);
1874 if (!DecodeIDBKey(&slice
, &key
)) {
1875 // TODO(jsbell): Return error.
1880 } // namespace content