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]
49 // The format of the journal is:
50 // {database_id (var int), blobKey (var int)}*.
51 // If the blobKey is kAllBlobsKey, the whole database should be deleted.
53 // <0, 0, 0, 4> => Live blob journal; same format. [LiveBlobJournalKey]
54 // <0, 0, 0, 100, database id>
55 // => Existence implies the database id is in the free list
56 // [DatabaseFreeListKey]
57 // <0, 0, 0, 201, origin, database name> => Database id (int) [DatabaseNameKey]
60 // Database metadata: [DatabaseMetaDataKey]
61 // ----------------------------------------
62 // The prefix is <database id, 0, 0> followed by a metadata type byte:
64 // <database id, 0, 0, 0> => origin name
65 // <database id, 0, 0, 1> => database name
66 // <database id, 0, 0, 2> => IDB string version data (obsolete)
67 // <database id, 0, 0, 3> => maximum allocated object store id
68 // <database id, 0, 0, 4> => IDB integer version (var int)
69 // <database id, 0, 0, 5> => blob key generator current number
72 // Object store metadata: [ObjectStoreMetaDataKey]
73 // -----------------------------------------------
74 // The prefix is <database id, 0, 0>, followed by a type byte (50), then the
75 // object store id (var int), then a metadata type byte.
77 // <database id, 0, 0, 50, object store id, 0> => object store name
78 // <database id, 0, 0, 50, object store id, 1> => key path
79 // <database id, 0, 0, 50, object store id, 2> => auto increment flag
80 // <database id, 0, 0, 50, object store id, 3> => is evictable
81 // <database id, 0, 0, 50, object store id, 4> => last "version" number
82 // <database id, 0, 0, 50, object store id, 5> => maximum allocated index id
83 // <database id, 0, 0, 50, object store id, 6> => has key path flag (obsolete)
84 // <database id, 0, 0, 50, object store id, 7> => key generator current number
86 // The key path was originally just a string (#1) or null (identified by flag,
87 // #6). To support null, string, or array the coding is now identified by the
88 // leading bytes in #1 - see EncodeIDBKeyPath.
90 // The "version" field is used to weed out stale index data. Whenever new
91 // object store data is inserted, it gets a new "version" number, and new
92 // index data is written with this number. When the index is used for
93 // look-ups, entries are validated against the "exists" entries, and records
94 // with old "version" numbers are deleted when they are encountered in
95 // GetPrimaryKeyViaIndex, IndexCursorImpl::LoadCurrentRow and
96 // IndexKeyCursorImpl::LoadCurrentRow.
99 // Index metadata: [IndexMetaDataKey]
100 // ----------------------------------
101 // The prefix is <database id, 0, 0>, followed by a type byte (100), then the
102 // object store id (var int), then the index id (var int), then a metadata
105 // <database id, 0, 0, 100, object store id, index id, 0> => index name
106 // <database id, 0, 0, 100, object store id, index id, 1> => unique flag
107 // <database id, 0, 0, 100, object store id, index id, 2> => key path
108 // <database id, 0, 0, 100, object store id, index id, 3> => multi-entry flag
111 // Other object store and index metadata
112 // -------------------------------------
113 // The prefix is <database id, 0, 0> followed by a type byte. The object
114 // store and index id are variable length integers, the names are variable
117 // <database id, 0, 0, 150, object store id>
118 // => existence implies the object store id is in the free list
119 // [ObjectStoreFreeListKey]
120 // <database id, 0, 0, 151, object store id, index id>
121 // => existence implies the index id is in the free list [IndexFreeListKey]
122 // <database id, 0, 0, 200, object store name>
123 // => object store id [ObjectStoreNamesKey]
124 // <database id, 0, 0, 201, object store id, index name>
125 // => index id [IndexNamesKey]
128 // Object store data: [ObjectStoreDataKey]
129 // ---------------------------------------
130 // The prefix is followed by a type byte and the encoded IDB primary key. The
131 // data has a "version" prefix followed by the serialized script value.
133 // <database id, object store id, 1, user key>
134 // => "version", serialized script value
137 // "Exists" entry: [ExistsEntryKey]
138 // --------------------------------
139 // The prefix is followed by a type byte and the encoded IDB primary key.
141 // <database id, object store id, 2, user key> => "version"
144 // Blob entry table: [BlobEntryKey]
145 // --------------------------------
147 // The prefix is followed by a type byte and the encoded IDB primary key.
149 // <database id, object store id, 3, user key> => array of IndexedDBBlobInfo
154 // The prefix is followed by a type byte, the encoded IDB index key, a
155 // "sequence" number (obsolete; var int), and the encoded IDB primary key.
157 // <database id, object store id, index id, index key, sequence number,
158 // primary key> => "version", primary key [IndexDataKey]
160 // The sequence number is obsolete; it was used to allow two entries with the
161 // same user (index) key in non-unique indexes prior to the inclusion of the
162 // primary key in the data.
164 // Note: In order to be compatible with LevelDB's Bloom filter each bit of the
165 // encoded key needs to used and "not ignored" by the comparator.
167 using base::StringPiece
;
168 using blink::WebIDBKeyType
;
169 using blink::WebIDBKeyTypeArray
;
170 using blink::WebIDBKeyTypeBinary
;
171 using blink::WebIDBKeyTypeDate
;
172 using blink::WebIDBKeyTypeInvalid
;
173 using blink::WebIDBKeyTypeMin
;
174 using blink::WebIDBKeyTypeNull
;
175 using blink::WebIDBKeyTypeNumber
;
176 using blink::WebIDBKeyTypeString
;
177 using blink::WebIDBKeyPathType
;
178 using blink::WebIDBKeyPathTypeArray
;
179 using blink::WebIDBKeyPathTypeNull
;
180 using blink::WebIDBKeyPathTypeString
;
184 // As most of the IndexedDBKeys and encoded values are short, we
185 // initialize some std::vectors with a default inline buffer size to reduce
186 // the memory re-allocations when the std::vectors are appended.
187 static const size_t kDefaultInlineBufferSize
= 32;
189 static const unsigned char kIndexedDBKeyNullTypeByte
= 0;
190 static const unsigned char kIndexedDBKeyStringTypeByte
= 1;
191 static const unsigned char kIndexedDBKeyDateTypeByte
= 2;
192 static const unsigned char kIndexedDBKeyNumberTypeByte
= 3;
193 static const unsigned char kIndexedDBKeyArrayTypeByte
= 4;
194 static const unsigned char kIndexedDBKeyMinKeyTypeByte
= 5;
195 static const unsigned char kIndexedDBKeyBinaryTypeByte
= 6;
197 static const unsigned char kIndexedDBKeyPathTypeCodedByte1
= 0;
198 static const unsigned char kIndexedDBKeyPathTypeCodedByte2
= 0;
200 static const unsigned char kObjectStoreDataIndexId
= 1;
201 static const unsigned char kExistsEntryIndexId
= 2;
202 static const unsigned char kBlobEntryIndexId
= 3;
204 static const unsigned char kSchemaVersionTypeByte
= 0;
205 static const unsigned char kMaxDatabaseIdTypeByte
= 1;
206 static const unsigned char kDataVersionTypeByte
= 2;
207 static const unsigned char kBlobJournalTypeByte
= 3;
208 static const unsigned char kLiveBlobJournalTypeByte
= 4;
209 static const unsigned char kMaxSimpleGlobalMetaDataTypeByte
=
210 5; // Insert before this and increment.
211 static const unsigned char kDatabaseFreeListTypeByte
= 100;
212 static const unsigned char kDatabaseNameTypeByte
= 201;
214 static const unsigned char kObjectStoreMetaDataTypeByte
= 50;
215 static const unsigned char kIndexMetaDataTypeByte
= 100;
216 static const unsigned char kObjectStoreFreeListTypeByte
= 150;
217 static const unsigned char kIndexFreeListTypeByte
= 151;
218 static const unsigned char kObjectStoreNamesTypeByte
= 200;
219 static const unsigned char kIndexNamesKeyTypeByte
= 201;
221 static const unsigned char kObjectMetaDataTypeMaximum
= 255;
222 static const unsigned char kIndexMetaDataTypeMaximum
= 255;
224 const unsigned char kMinimumIndexId
= 30;
226 inline void EncodeIntSafely(int64 value
, int64 max
, std::string
* into
) {
227 DCHECK_LE(value
, max
);
228 return EncodeInt(value
, into
);
231 std::string
MaxIDBKey() {
233 EncodeByte(kIndexedDBKeyNullTypeByte
, &ret
);
237 std::string
MinIDBKey() {
239 EncodeByte(kIndexedDBKeyMinKeyTypeByte
, &ret
);
243 void EncodeByte(unsigned char value
, std::string
* into
) {
244 into
->push_back(value
);
247 void EncodeBool(bool value
, std::string
* into
) {
248 into
->push_back(value
? 1 : 0);
251 void EncodeInt(int64 value
, std::string
* into
) {
253 // Exercised by unit tests in debug only.
256 uint64 n
= static_cast<uint64
>(value
);
265 void EncodeVarInt(int64 value
, std::string
* into
) {
267 // Exercised by unit tests in debug only.
270 uint64 n
= static_cast<uint64
>(value
);
273 unsigned char c
= n
& 0x7f;
281 void EncodeString(const base::string16
& value
, std::string
* into
) {
284 // Backing store is UTF-16BE, convert from host endianness.
285 size_t length
= value
.length();
286 size_t current
= into
->size();
287 into
->resize(into
->size() + length
* sizeof(base::char16
));
289 const base::char16
* src
= value
.c_str();
291 reinterpret_cast<base::char16
*>(&*into
->begin() + current
);
292 for (unsigned i
= 0; i
< length
; ++i
)
293 *dst
++ = htons(*src
++);
296 void EncodeBinary(const std::string
& value
, std::string
* into
) {
297 EncodeVarInt(value
.length(), into
);
298 into
->append(value
.begin(), value
.end());
299 DCHECK(into
->size() >= value
.size());
302 void EncodeStringWithLength(const base::string16
& value
, std::string
* into
) {
303 EncodeVarInt(value
.length(), into
);
304 EncodeString(value
, into
);
307 void EncodeDouble(double value
, std::string
* into
) {
308 // This always has host endianness.
309 const char* p
= reinterpret_cast<char*>(&value
);
310 into
->insert(into
->end(), p
, p
+ sizeof(value
));
313 void EncodeIDBKey(const IndexedDBKey
& value
, std::string
* into
) {
314 size_t previous_size
= into
->size();
315 DCHECK(value
.IsValid());
316 switch (value
.type()) {
317 case WebIDBKeyTypeArray
: {
318 EncodeByte(kIndexedDBKeyArrayTypeByte
, into
);
319 size_t length
= value
.array().size();
320 EncodeVarInt(length
, into
);
321 for (size_t i
= 0; i
< length
; ++i
)
322 EncodeIDBKey(value
.array()[i
], into
);
323 DCHECK_GT(into
->size(), previous_size
);
326 case WebIDBKeyTypeBinary
:
327 EncodeByte(kIndexedDBKeyBinaryTypeByte
, into
);
328 EncodeBinary(value
.binary(), into
);
329 DCHECK_GT(into
->size(), previous_size
);
331 case WebIDBKeyTypeString
:
332 EncodeByte(kIndexedDBKeyStringTypeByte
, into
);
333 EncodeStringWithLength(value
.string(), into
);
334 DCHECK_GT(into
->size(), previous_size
);
336 case WebIDBKeyTypeDate
:
337 EncodeByte(kIndexedDBKeyDateTypeByte
, into
);
338 EncodeDouble(value
.date(), into
);
339 DCHECK_EQ(9u, static_cast<size_t>(into
->size() - previous_size
));
341 case WebIDBKeyTypeNumber
:
342 EncodeByte(kIndexedDBKeyNumberTypeByte
, into
);
343 EncodeDouble(value
.number(), into
);
344 DCHECK_EQ(9u, static_cast<size_t>(into
->size() - previous_size
));
346 case WebIDBKeyTypeNull
:
347 case WebIDBKeyTypeInvalid
:
348 case WebIDBKeyTypeMin
:
351 EncodeByte(kIndexedDBKeyNullTypeByte
, into
);
356 void EncodeIDBKeyPath(const IndexedDBKeyPath
& value
, std::string
* into
) {
357 // May be typed, or may be a raw string. An invalid leading
358 // byte is used to identify typed coding. New records are
359 // always written as typed.
360 EncodeByte(kIndexedDBKeyPathTypeCodedByte1
, into
);
361 EncodeByte(kIndexedDBKeyPathTypeCodedByte2
, into
);
362 EncodeByte(static_cast<char>(value
.type()), into
);
363 switch (value
.type()) {
364 case WebIDBKeyPathTypeNull
:
366 case WebIDBKeyPathTypeString
: {
367 EncodeStringWithLength(value
.string(), into
);
370 case WebIDBKeyPathTypeArray
: {
371 const std::vector
<base::string16
>& array
= value
.array();
372 size_t count
= array
.size();
373 EncodeVarInt(count
, into
);
374 for (size_t i
= 0; i
< count
; ++i
) {
375 EncodeStringWithLength(array
[i
], into
);
382 void EncodeBlobJournal(const BlobJournalType
& journal
, std::string
* into
) {
383 for (const auto& iter
: journal
) {
384 EncodeVarInt(iter
.first
, into
);
385 EncodeVarInt(iter
.second
, into
);
389 bool DecodeByte(StringPiece
* slice
, unsigned char* value
) {
393 *value
= (*slice
)[0];
394 slice
->remove_prefix(1);
398 bool DecodeBool(StringPiece
* slice
, bool* value
) {
402 *value
= !!(*slice
)[0];
403 slice
->remove_prefix(1);
407 bool DecodeInt(StringPiece
* slice
, int64
* value
) {
411 StringPiece::const_iterator it
= slice
->begin();
414 while (it
!= slice
->end()) {
415 unsigned char c
= *it
++;
416 ret
|= static_cast<int64
>(c
) << shift
;
420 slice
->remove_prefix(it
- slice
->begin());
424 bool DecodeVarInt(StringPiece
* slice
, int64
* value
) {
428 StringPiece::const_iterator it
= slice
->begin();
432 if (it
== slice
->end())
435 unsigned char c
= *it
;
436 ret
|= static_cast<int64
>(c
& 0x7f) << shift
;
438 } while (*it
++ & 0x80);
440 slice
->remove_prefix(it
- slice
->begin());
444 bool DecodeString(StringPiece
* slice
, base::string16
* value
) {
445 if (slice
->empty()) {
450 // Backing store is UTF-16BE, convert to host endianness.
451 DCHECK(!(slice
->size() % sizeof(base::char16
)));
452 size_t length
= slice
->size() / sizeof(base::char16
);
453 base::string16 decoded
;
454 decoded
.reserve(length
);
455 const base::char16
* encoded
=
456 reinterpret_cast<const base::char16
*>(slice
->begin());
457 for (unsigned i
= 0; i
< length
; ++i
)
458 decoded
.push_back(ntohs(*encoded
++));
461 slice
->remove_prefix(length
* sizeof(base::char16
));
465 bool DecodeStringWithLength(StringPiece
* slice
, base::string16
* value
) {
470 if (!DecodeVarInt(slice
, &length
) || length
< 0)
472 size_t bytes
= length
* sizeof(base::char16
);
473 if (slice
->size() < bytes
)
476 StringPiece
subpiece(slice
->begin(), bytes
);
477 slice
->remove_prefix(bytes
);
478 if (!DecodeString(&subpiece
, value
))
484 bool DecodeBinary(StringPiece
* slice
, std::string
* value
) {
489 if (!DecodeVarInt(slice
, &length
) || length
< 0)
491 size_t size
= length
;
492 if (slice
->size() < size
)
495 value
->assign(slice
->begin(), size
);
496 slice
->remove_prefix(size
);
500 bool DecodeIDBKey(StringPiece
* slice
, scoped_ptr
<IndexedDBKey
>* value
) {
504 unsigned char type
= (*slice
)[0];
505 slice
->remove_prefix(1);
508 case kIndexedDBKeyNullTypeByte
:
509 *value
= make_scoped_ptr(new IndexedDBKey());
512 case kIndexedDBKeyArrayTypeByte
: {
514 if (!DecodeVarInt(slice
, &length
) || length
< 0)
516 IndexedDBKey::KeyArray array
;
518 scoped_ptr
<IndexedDBKey
> key
;
519 if (!DecodeIDBKey(slice
, &key
))
521 array
.push_back(*key
);
523 *value
= make_scoped_ptr(new IndexedDBKey(array
));
526 case kIndexedDBKeyBinaryTypeByte
: {
528 if (!DecodeBinary(slice
, &binary
))
530 *value
= make_scoped_ptr(new IndexedDBKey(binary
));
533 case kIndexedDBKeyStringTypeByte
: {
535 if (!DecodeStringWithLength(slice
, &s
))
537 *value
= make_scoped_ptr(new IndexedDBKey(s
));
540 case kIndexedDBKeyDateTypeByte
: {
542 if (!DecodeDouble(slice
, &d
))
544 *value
= make_scoped_ptr(new IndexedDBKey(d
, WebIDBKeyTypeDate
));
547 case kIndexedDBKeyNumberTypeByte
: {
549 if (!DecodeDouble(slice
, &d
))
551 *value
= make_scoped_ptr(new IndexedDBKey(d
, WebIDBKeyTypeNumber
));
560 bool DecodeDouble(StringPiece
* slice
, double* value
) {
561 if (slice
->size() < sizeof(*value
))
564 memcpy(value
, slice
->begin(), sizeof(*value
));
565 slice
->remove_prefix(sizeof(*value
));
569 bool DecodeIDBKeyPath(StringPiece
* slice
, IndexedDBKeyPath
* value
) {
570 // May be typed, or may be a raw string. An invalid leading
571 // byte sequence is used to identify typed coding. New records are
572 // always written as typed.
573 if (slice
->size() < 3 || (*slice
)[0] != kIndexedDBKeyPathTypeCodedByte1
||
574 (*slice
)[1] != kIndexedDBKeyPathTypeCodedByte2
) {
576 if (!DecodeString(slice
, &s
))
578 *value
= IndexedDBKeyPath(s
);
582 slice
->remove_prefix(2);
583 DCHECK(!slice
->empty());
584 WebIDBKeyPathType type
= static_cast<WebIDBKeyPathType
>((*slice
)[0]);
585 slice
->remove_prefix(1);
588 case WebIDBKeyPathTypeNull
:
589 DCHECK(slice
->empty());
590 *value
= IndexedDBKeyPath();
592 case WebIDBKeyPathTypeString
: {
593 base::string16 string
;
594 if (!DecodeStringWithLength(slice
, &string
))
596 DCHECK(slice
->empty());
597 *value
= IndexedDBKeyPath(string
);
600 case WebIDBKeyPathTypeArray
: {
601 std::vector
<base::string16
> array
;
603 if (!DecodeVarInt(slice
, &count
))
607 base::string16 string
;
608 if (!DecodeStringWithLength(slice
, &string
))
610 array
.push_back(string
);
612 DCHECK(slice
->empty());
613 *value
= IndexedDBKeyPath(array
);
621 bool DecodeBlobJournal(StringPiece
* slice
, BlobJournalType
* journal
) {
622 BlobJournalType output
;
623 while (!slice
->empty()) {
624 int64 database_id
= -1;
626 if (!DecodeVarInt(slice
, &database_id
))
628 if (!KeyPrefix::IsValidDatabaseId(database_id
))
630 if (!DecodeVarInt(slice
, &blob_key
))
632 if (!DatabaseMetaDataKey::IsValidBlobKey(blob_key
) &&
633 (blob_key
!= DatabaseMetaDataKey::kAllBlobsKey
)) {
636 output
.push_back(std::make_pair(database_id
, blob_key
));
638 journal
->swap(output
);
642 bool ConsumeEncodedIDBKey(StringPiece
* slice
) {
643 unsigned char type
= (*slice
)[0];
644 slice
->remove_prefix(1);
647 case kIndexedDBKeyNullTypeByte
:
648 case kIndexedDBKeyMinKeyTypeByte
:
650 case kIndexedDBKeyArrayTypeByte
: {
652 if (!DecodeVarInt(slice
, &length
))
655 if (!ConsumeEncodedIDBKey(slice
))
660 case kIndexedDBKeyBinaryTypeByte
: {
662 if (!DecodeVarInt(slice
, &length
) || length
< 0)
664 if (slice
->size() < static_cast<size_t>(length
))
666 slice
->remove_prefix(length
);
669 case kIndexedDBKeyStringTypeByte
: {
671 if (!DecodeVarInt(slice
, &length
) || length
< 0)
673 if (slice
->size() < static_cast<size_t>(length
) * sizeof(base::char16
))
675 slice
->remove_prefix(length
* sizeof(base::char16
));
678 case kIndexedDBKeyDateTypeByte
:
679 case kIndexedDBKeyNumberTypeByte
:
680 if (slice
->size() < sizeof(double))
682 slice
->remove_prefix(sizeof(double));
689 bool ExtractEncodedIDBKey(StringPiece
* slice
, std::string
* result
) {
690 const char* start
= slice
->begin();
691 if (!ConsumeEncodedIDBKey(slice
))
695 result
->assign(start
, slice
->begin());
699 static WebIDBKeyType
KeyTypeByteToKeyType(unsigned char type
) {
701 case kIndexedDBKeyNullTypeByte
:
702 return WebIDBKeyTypeInvalid
;
703 case kIndexedDBKeyArrayTypeByte
:
704 return WebIDBKeyTypeArray
;
705 case kIndexedDBKeyBinaryTypeByte
:
706 return WebIDBKeyTypeBinary
;
707 case kIndexedDBKeyStringTypeByte
:
708 return WebIDBKeyTypeString
;
709 case kIndexedDBKeyDateTypeByte
:
710 return WebIDBKeyTypeDate
;
711 case kIndexedDBKeyNumberTypeByte
:
712 return WebIDBKeyTypeNumber
;
713 case kIndexedDBKeyMinKeyTypeByte
:
714 return WebIDBKeyTypeMin
;
718 return WebIDBKeyTypeInvalid
;
721 int CompareEncodedStringsWithLength(StringPiece
* slice1
,
725 if (!DecodeVarInt(slice1
, &len1
) || !DecodeVarInt(slice2
, &len2
)) {
731 if (len1
< 0 || len2
< 0) {
735 DCHECK_GE(slice1
->size(), len1
* sizeof(base::char16
));
736 DCHECK_GE(slice2
->size(), len2
* sizeof(base::char16
));
737 if (slice1
->size() < len1
* sizeof(base::char16
) ||
738 slice2
->size() < len2
* sizeof(base::char16
)) {
743 // Extract the string data, and advance the passed slices.
744 StringPiece
string1(slice1
->begin(), len1
* sizeof(base::char16
));
745 StringPiece
string2(slice2
->begin(), len2
* sizeof(base::char16
));
746 slice1
->remove_prefix(len1
* sizeof(base::char16
));
747 slice2
->remove_prefix(len2
* sizeof(base::char16
));
750 // Strings are UTF-16BE encoded, so a simple memcmp is sufficient.
751 return string1
.compare(string2
);
754 int CompareEncodedBinary(StringPiece
* slice1
,
758 if (!DecodeVarInt(slice1
, &len1
) || !DecodeVarInt(slice2
, &len2
)) {
764 if (len1
< 0 || len2
< 0) {
771 DCHECK_GE(slice1
->size(), size1
);
772 DCHECK_GE(slice2
->size(), size2
);
773 if (slice1
->size() < size1
|| slice2
->size() < size2
) {
778 // Extract the binary data, and advance the passed slices.
779 StringPiece
binary1(slice1
->begin(), size1
);
780 StringPiece
binary2(slice2
->begin(), size2
);
781 slice1
->remove_prefix(size1
);
782 slice2
->remove_prefix(size2
);
785 // This is the same as a memcmp()
786 return binary1
.compare(binary2
);
789 static int CompareInts(int64 a
, int64 b
) {
791 // Exercised by unit tests in debug only.
803 static inline int CompareSizes(size_t a
, size_t b
) {
811 static int CompareTypes(WebIDBKeyType a
, WebIDBKeyType b
) { return b
- a
; }
813 int CompareEncodedIDBKeys(StringPiece
* slice_a
,
814 StringPiece
* slice_b
,
816 DCHECK(!slice_a
->empty());
817 DCHECK(!slice_b
->empty());
819 unsigned char type_a
= (*slice_a
)[0];
820 unsigned char type_b
= (*slice_b
)[0];
821 slice_a
->remove_prefix(1);
822 slice_b
->remove_prefix(1);
824 if (int x
= CompareTypes(KeyTypeByteToKeyType(type_a
),
825 KeyTypeByteToKeyType(type_b
)))
829 case kIndexedDBKeyNullTypeByte
:
830 case kIndexedDBKeyMinKeyTypeByte
:
831 // Null type or max type; no payload to compare.
833 case kIndexedDBKeyArrayTypeByte
: {
834 int64 length_a
, length_b
;
835 if (!DecodeVarInt(slice_a
, &length_a
) ||
836 !DecodeVarInt(slice_b
, &length_b
)) {
840 for (int64 i
= 0; i
< length_a
&& i
< length_b
; ++i
) {
841 int result
= CompareEncodedIDBKeys(slice_a
, slice_b
, ok
);
845 return length_a
- length_b
;
847 case kIndexedDBKeyBinaryTypeByte
:
848 return CompareEncodedBinary(slice_a
, slice_b
, ok
);
849 case kIndexedDBKeyStringTypeByte
:
850 return CompareEncodedStringsWithLength(slice_a
, slice_b
, ok
);
851 case kIndexedDBKeyDateTypeByte
:
852 case kIndexedDBKeyNumberTypeByte
: {
854 if (!DecodeDouble(slice_a
, &d
) || !DecodeDouble(slice_b
, &e
)) {
872 template <typename KeyType
>
873 int Compare(const StringPiece
& a
,
874 const StringPiece
& b
,
875 bool only_compare_index_keys
,
880 StringPiece
slice_a(a
);
881 if (!KeyType::Decode(&slice_a
, &key_a
)) {
885 StringPiece
slice_b(b
);
886 if (!KeyType::Decode(&slice_b
, &key_b
)) {
892 return key_a
.Compare(key_b
);
895 template <typename KeyType
>
896 int CompareSuffix(StringPiece
* a
,
898 bool only_compare_index_keys
,
905 int CompareSuffix
<ExistsEntryKey
>(StringPiece
* slice_a
,
906 StringPiece
* slice_b
,
907 bool only_compare_index_keys
,
909 DCHECK(!slice_a
->empty());
910 DCHECK(!slice_b
->empty());
911 return CompareEncodedIDBKeys(slice_a
, slice_b
, ok
);
915 int CompareSuffix
<ObjectStoreDataKey
>(StringPiece
* slice_a
,
916 StringPiece
* slice_b
,
917 bool only_compare_index_keys
,
919 return CompareEncodedIDBKeys(slice_a
, slice_b
, ok
);
923 int CompareSuffix
<BlobEntryKey
>(StringPiece
* slice_a
,
924 StringPiece
* slice_b
,
925 bool only_compare_index_keys
,
927 return CompareEncodedIDBKeys(slice_a
, slice_b
, ok
);
931 int CompareSuffix
<IndexDataKey
>(StringPiece
* slice_a
,
932 StringPiece
* slice_b
,
933 bool only_compare_index_keys
,
936 int result
= CompareEncodedIDBKeys(slice_a
, slice_b
, ok
);
939 if (only_compare_index_keys
)
942 // sequence number [optional]
943 int64 sequence_number_a
= -1;
944 int64 sequence_number_b
= -1;
945 if (!slice_a
->empty() && !DecodeVarInt(slice_a
, &sequence_number_a
))
947 if (!slice_b
->empty() && !DecodeVarInt(slice_b
, &sequence_number_b
))
950 if (slice_a
->empty() || slice_b
->empty())
951 return CompareSizes(slice_a
->size(), slice_b
->size());
953 // primary key [optional]
954 result
= CompareEncodedIDBKeys(slice_a
, slice_b
, ok
);
958 return CompareInts(sequence_number_a
, sequence_number_b
);
961 int Compare(const StringPiece
& a
,
962 const StringPiece
& b
,
963 bool only_compare_index_keys
,
965 StringPiece
slice_a(a
);
966 StringPiece
slice_b(b
);
969 bool ok_a
= KeyPrefix::Decode(&slice_a
, &prefix_a
);
970 bool ok_b
= KeyPrefix::Decode(&slice_b
, &prefix_b
);
973 if (!ok_a
|| !ok_b
) {
979 if (int x
= prefix_a
.Compare(prefix_b
))
982 switch (prefix_a
.type()) {
983 case KeyPrefix::GLOBAL_METADATA
: {
984 DCHECK(!slice_a
.empty());
985 DCHECK(!slice_b
.empty());
987 unsigned char type_byte_a
;
988 if (!DecodeByte(&slice_a
, &type_byte_a
)) {
993 unsigned char type_byte_b
;
994 if (!DecodeByte(&slice_b
, &type_byte_b
)) {
999 if (int x
= type_byte_a
- type_byte_b
)
1001 if (type_byte_a
< kMaxSimpleGlobalMetaDataTypeByte
)
1004 // Compare<> is used (which re-decodes the prefix) rather than an
1005 // specialized CompareSuffix<> because metadata is relatively uncommon
1008 if (type_byte_a
== kDatabaseFreeListTypeByte
) {
1009 // TODO(jsbell): No need to pass only_compare_index_keys through here.
1010 return Compare
<DatabaseFreeListKey
>(a
, b
, only_compare_index_keys
, ok
);
1012 if (type_byte_a
== kDatabaseNameTypeByte
) {
1013 return Compare
<DatabaseNameKey
>(
1014 a
, b
, /*only_compare_index_keys*/ false, ok
);
1019 case KeyPrefix::DATABASE_METADATA
: {
1020 DCHECK(!slice_a
.empty());
1021 DCHECK(!slice_b
.empty());
1023 unsigned char type_byte_a
;
1024 if (!DecodeByte(&slice_a
, &type_byte_a
)) {
1029 unsigned char type_byte_b
;
1030 if (!DecodeByte(&slice_b
, &type_byte_b
)) {
1035 if (int x
= type_byte_a
- type_byte_b
)
1037 if (type_byte_a
< DatabaseMetaDataKey::MAX_SIMPLE_METADATA_TYPE
)
1040 // Compare<> is used (which re-decodes the prefix) rather than an
1041 // specialized CompareSuffix<> because metadata is relatively uncommon
1044 if (type_byte_a
== kObjectStoreMetaDataTypeByte
) {
1045 // TODO(jsbell): No need to pass only_compare_index_keys through here.
1046 return Compare
<ObjectStoreMetaDataKey
>(
1047 a
, b
, only_compare_index_keys
, ok
);
1049 if (type_byte_a
== kIndexMetaDataTypeByte
) {
1050 return Compare
<IndexMetaDataKey
>(
1051 a
, b
, /*only_compare_index_keys*/ false, ok
);
1053 if (type_byte_a
== kObjectStoreFreeListTypeByte
) {
1054 return Compare
<ObjectStoreFreeListKey
>(
1055 a
, b
, only_compare_index_keys
, ok
);
1057 if (type_byte_a
== kIndexFreeListTypeByte
) {
1058 return Compare
<IndexFreeListKey
>(
1059 a
, b
, /*only_compare_index_keys*/ false, ok
);
1061 if (type_byte_a
== kObjectStoreNamesTypeByte
) {
1062 // TODO(jsbell): No need to pass only_compare_index_keys through here.
1063 return Compare
<ObjectStoreNamesKey
>(
1064 a
, b
, only_compare_index_keys
, ok
);
1066 if (type_byte_a
== kIndexNamesKeyTypeByte
) {
1067 return Compare
<IndexNamesKey
>(
1068 a
, b
, /*only_compare_index_keys*/ false, ok
);
1073 case KeyPrefix::OBJECT_STORE_DATA
: {
1074 // Provide a stable ordering for invalid data.
1075 if (slice_a
.empty() || slice_b
.empty())
1076 return CompareSizes(slice_a
.size(), slice_b
.size());
1078 return CompareSuffix
<ObjectStoreDataKey
>(
1079 &slice_a
, &slice_b
, /*only_compare_index_keys*/ false, ok
);
1082 case KeyPrefix::EXISTS_ENTRY
: {
1083 // Provide a stable ordering for invalid data.
1084 if (slice_a
.empty() || slice_b
.empty())
1085 return CompareSizes(slice_a
.size(), slice_b
.size());
1087 return CompareSuffix
<ExistsEntryKey
>(
1088 &slice_a
, &slice_b
, /*only_compare_index_keys*/ false, ok
);
1091 case KeyPrefix::BLOB_ENTRY
: {
1092 // Provide a stable ordering for invalid data.
1093 if (slice_a
.empty() || slice_b
.empty())
1094 return CompareSizes(slice_a
.size(), slice_b
.size());
1096 return CompareSuffix
<BlobEntryKey
>(
1097 &slice_a
, &slice_b
, /*only_compare_index_keys*/ false, ok
);
1100 case KeyPrefix::INDEX_DATA
: {
1101 // Provide a stable ordering for invalid data.
1102 if (slice_a
.empty() || slice_b
.empty())
1103 return CompareSizes(slice_a
.size(), slice_b
.size());
1105 return CompareSuffix
<IndexDataKey
>(
1106 &slice_a
, &slice_b
, only_compare_index_keys
, ok
);
1109 case KeyPrefix::INVALID_TYPE
:
1120 int Compare(const StringPiece
& a
,
1121 const StringPiece
& b
,
1122 bool only_compare_index_keys
) {
1124 int result
= Compare(a
, b
, only_compare_index_keys
, &ok
);
1131 KeyPrefix::KeyPrefix()
1132 : database_id_(INVALID_TYPE
),
1133 object_store_id_(INVALID_TYPE
),
1134 index_id_(INVALID_TYPE
) {}
1136 KeyPrefix::KeyPrefix(int64 database_id
)
1137 : database_id_(database_id
), object_store_id_(0), index_id_(0) {
1138 DCHECK(KeyPrefix::IsValidDatabaseId(database_id
));
1141 KeyPrefix::KeyPrefix(int64 database_id
, int64 object_store_id
)
1142 : database_id_(database_id
),
1143 object_store_id_(object_store_id
),
1145 DCHECK(KeyPrefix::IsValidDatabaseId(database_id
));
1146 DCHECK(KeyPrefix::IsValidObjectStoreId(object_store_id
));
1149 KeyPrefix::KeyPrefix(int64 database_id
, int64 object_store_id
, int64 index_id
)
1150 : database_id_(database_id
),
1151 object_store_id_(object_store_id
),
1152 index_id_(index_id
) {
1153 DCHECK(KeyPrefix::IsValidDatabaseId(database_id
));
1154 DCHECK(KeyPrefix::IsValidObjectStoreId(object_store_id
));
1155 DCHECK(KeyPrefix::IsValidIndexId(index_id
));
1158 KeyPrefix::KeyPrefix(enum Type type
,
1160 int64 object_store_id
,
1162 : database_id_(database_id
),
1163 object_store_id_(object_store_id
),
1164 index_id_(index_id
) {
1165 DCHECK_EQ(type
, INVALID_TYPE
);
1166 DCHECK(KeyPrefix::IsValidDatabaseId(database_id
));
1167 DCHECK(KeyPrefix::IsValidObjectStoreId(object_store_id
));
1170 KeyPrefix
KeyPrefix::CreateWithSpecialIndex(int64 database_id
,
1171 int64 object_store_id
,
1173 DCHECK(KeyPrefix::IsValidDatabaseId(database_id
));
1174 DCHECK(KeyPrefix::IsValidObjectStoreId(object_store_id
));
1176 return KeyPrefix(INVALID_TYPE
, database_id
, object_store_id
, index_id
);
1179 bool KeyPrefix::IsValidDatabaseId(int64 database_id
) {
1180 return (database_id
> 0) && (database_id
< KeyPrefix::kMaxDatabaseId
);
1183 bool KeyPrefix::IsValidObjectStoreId(int64 object_store_id
) {
1184 return (object_store_id
> 0) &&
1185 (object_store_id
< KeyPrefix::kMaxObjectStoreId
);
1188 bool KeyPrefix::IsValidIndexId(int64 index_id
) {
1189 return (index_id
>= kMinimumIndexId
) && (index_id
< KeyPrefix::kMaxIndexId
);
1192 bool KeyPrefix::Decode(StringPiece
* slice
, KeyPrefix
* result
) {
1193 unsigned char first_byte
;
1194 if (!DecodeByte(slice
, &first_byte
))
1197 size_t database_id_bytes
= ((first_byte
>> 5) & 0x7) + 1;
1198 size_t object_store_id_bytes
= ((first_byte
>> 2) & 0x7) + 1;
1199 size_t index_id_bytes
= (first_byte
& 0x3) + 1;
1201 if (database_id_bytes
+ object_store_id_bytes
+ index_id_bytes
>
1206 StringPiece
tmp(slice
->begin(), database_id_bytes
);
1207 if (!DecodeInt(&tmp
, &result
->database_id_
))
1210 slice
->remove_prefix(database_id_bytes
);
1212 StringPiece
tmp(slice
->begin(), object_store_id_bytes
);
1213 if (!DecodeInt(&tmp
, &result
->object_store_id_
))
1216 slice
->remove_prefix(object_store_id_bytes
);
1218 StringPiece
tmp(slice
->begin(), index_id_bytes
);
1219 if (!DecodeInt(&tmp
, &result
->index_id_
))
1222 slice
->remove_prefix(index_id_bytes
);
1226 std::string
KeyPrefix::EncodeEmpty() {
1227 const std::string
result(4, 0);
1228 DCHECK(EncodeInternal(0, 0, 0) == std::string(4, 0));
1232 std::string
KeyPrefix::Encode() const {
1233 DCHECK(database_id_
!= kInvalidId
);
1234 DCHECK(object_store_id_
!= kInvalidId
);
1235 DCHECK(index_id_
!= kInvalidId
);
1236 return EncodeInternal(database_id_
, object_store_id_
, index_id_
);
1239 std::string
KeyPrefix::EncodeInternal(int64 database_id
,
1240 int64 object_store_id
,
1242 std::string database_id_string
;
1243 std::string object_store_id_string
;
1244 std::string index_id_string
;
1246 EncodeIntSafely(database_id
, kMaxDatabaseId
, &database_id_string
);
1247 EncodeIntSafely(object_store_id
, kMaxObjectStoreId
, &object_store_id_string
);
1248 EncodeIntSafely(index_id
, kMaxIndexId
, &index_id_string
);
1250 DCHECK(database_id_string
.size() <= kMaxDatabaseIdSizeBytes
);
1251 DCHECK(object_store_id_string
.size() <= kMaxObjectStoreIdSizeBytes
);
1252 DCHECK(index_id_string
.size() <= kMaxIndexIdSizeBytes
);
1254 unsigned char first_byte
=
1255 (database_id_string
.size() - 1) << (kMaxObjectStoreIdSizeBits
+
1256 kMaxIndexIdSizeBits
) |
1257 (object_store_id_string
.size() - 1) << kMaxIndexIdSizeBits
|
1258 (index_id_string
.size() - 1);
1259 static_assert(kMaxDatabaseIdSizeBits
+ kMaxObjectStoreIdSizeBits
+
1260 kMaxIndexIdSizeBits
==
1261 sizeof(first_byte
) * 8,
1262 "cannot encode ids");
1264 ret
.reserve(kDefaultInlineBufferSize
);
1265 ret
.push_back(first_byte
);
1266 ret
.append(database_id_string
);
1267 ret
.append(object_store_id_string
);
1268 ret
.append(index_id_string
);
1270 DCHECK_LE(ret
.size(), kDefaultInlineBufferSize
);
1274 int KeyPrefix::Compare(const KeyPrefix
& other
) const {
1275 DCHECK(database_id_
!= kInvalidId
);
1276 DCHECK(object_store_id_
!= kInvalidId
);
1277 DCHECK(index_id_
!= kInvalidId
);
1279 if (database_id_
!= other
.database_id_
)
1280 return CompareInts(database_id_
, other
.database_id_
);
1281 if (object_store_id_
!= other
.object_store_id_
)
1282 return CompareInts(object_store_id_
, other
.object_store_id_
);
1283 if (index_id_
!= other
.index_id_
)
1284 return CompareInts(index_id_
, other
.index_id_
);
1288 KeyPrefix::Type
KeyPrefix::type() const {
1289 DCHECK(database_id_
!= kInvalidId
);
1290 DCHECK(object_store_id_
!= kInvalidId
);
1291 DCHECK(index_id_
!= kInvalidId
);
1294 return GLOBAL_METADATA
;
1295 if (!object_store_id_
)
1296 return DATABASE_METADATA
;
1297 if (index_id_
== kObjectStoreDataIndexId
)
1298 return OBJECT_STORE_DATA
;
1299 if (index_id_
== kExistsEntryIndexId
)
1300 return EXISTS_ENTRY
;
1301 if (index_id_
== kBlobEntryIndexId
)
1303 if (index_id_
>= kMinimumIndexId
)
1307 return INVALID_TYPE
;
1310 std::string
SchemaVersionKey::Encode() {
1311 std::string ret
= KeyPrefix::EncodeEmpty();
1312 ret
.push_back(kSchemaVersionTypeByte
);
1316 std::string
MaxDatabaseIdKey::Encode() {
1317 std::string ret
= KeyPrefix::EncodeEmpty();
1318 ret
.push_back(kMaxDatabaseIdTypeByte
);
1322 std::string
DataVersionKey::Encode() {
1323 std::string ret
= KeyPrefix::EncodeEmpty();
1324 ret
.push_back(kDataVersionTypeByte
);
1328 std::string
BlobJournalKey::Encode() {
1329 std::string ret
= KeyPrefix::EncodeEmpty();
1330 ret
.push_back(kBlobJournalTypeByte
);
1334 std::string
LiveBlobJournalKey::Encode() {
1335 std::string ret
= KeyPrefix::EncodeEmpty();
1336 ret
.push_back(kLiveBlobJournalTypeByte
);
1340 DatabaseFreeListKey::DatabaseFreeListKey() : database_id_(-1) {}
1342 bool DatabaseFreeListKey::Decode(StringPiece
* slice
,
1343 DatabaseFreeListKey
* result
) {
1345 if (!KeyPrefix::Decode(slice
, &prefix
))
1347 DCHECK(!prefix
.database_id_
);
1348 DCHECK(!prefix
.object_store_id_
);
1349 DCHECK(!prefix
.index_id_
);
1350 unsigned char type_byte
= 0;
1351 if (!DecodeByte(slice
, &type_byte
))
1353 DCHECK_EQ(type_byte
, kDatabaseFreeListTypeByte
);
1354 if (!DecodeVarInt(slice
, &result
->database_id_
))
1359 std::string
DatabaseFreeListKey::Encode(int64 database_id
) {
1360 std::string ret
= KeyPrefix::EncodeEmpty();
1361 ret
.push_back(kDatabaseFreeListTypeByte
);
1362 EncodeVarInt(database_id
, &ret
);
1366 std::string
DatabaseFreeListKey::EncodeMaxKey() {
1367 return Encode(std::numeric_limits
<int64
>::max());
1370 int64
DatabaseFreeListKey::DatabaseId() const {
1371 DCHECK_GE(database_id_
, 0);
1372 return database_id_
;
1375 int DatabaseFreeListKey::Compare(const DatabaseFreeListKey
& other
) const {
1376 DCHECK_GE(database_id_
, 0);
1377 return CompareInts(database_id_
, other
.database_id_
);
1380 bool DatabaseNameKey::Decode(StringPiece
* slice
, DatabaseNameKey
* result
) {
1382 if (!KeyPrefix::Decode(slice
, &prefix
))
1384 DCHECK(!prefix
.database_id_
);
1385 DCHECK(!prefix
.object_store_id_
);
1386 DCHECK(!prefix
.index_id_
);
1387 unsigned char type_byte
= 0;
1388 if (!DecodeByte(slice
, &type_byte
))
1390 DCHECK_EQ(type_byte
, kDatabaseNameTypeByte
);
1391 if (!DecodeStringWithLength(slice
, &result
->origin_
))
1393 if (!DecodeStringWithLength(slice
, &result
->database_name_
))
1398 std::string
DatabaseNameKey::Encode(const std::string
& origin_identifier
,
1399 const base::string16
& database_name
) {
1400 std::string ret
= KeyPrefix::EncodeEmpty();
1401 ret
.push_back(kDatabaseNameTypeByte
);
1402 EncodeStringWithLength(base::ASCIIToUTF16(origin_identifier
), &ret
);
1403 EncodeStringWithLength(database_name
, &ret
);
1407 std::string
DatabaseNameKey::EncodeMinKeyForOrigin(
1408 const std::string
& origin_identifier
) {
1409 return Encode(origin_identifier
, base::string16());
1412 std::string
DatabaseNameKey::EncodeStopKeyForOrigin(
1413 const std::string
& origin_identifier
) {
1414 // just after origin in collation order
1415 return EncodeMinKeyForOrigin(origin_identifier
+ '\x01');
1418 int DatabaseNameKey::Compare(const DatabaseNameKey
& other
) {
1419 if (int x
= origin_
.compare(other
.origin_
))
1421 return database_name_
.compare(other
.database_name_
);
1424 bool DatabaseMetaDataKey::IsValidBlobKey(int64 blob_key
) {
1425 return blob_key
>= kBlobKeyGeneratorInitialNumber
;
1428 const int64
DatabaseMetaDataKey::kAllBlobsKey
= 1;
1429 const int64
DatabaseMetaDataKey::kBlobKeyGeneratorInitialNumber
= 2;
1430 const int64
DatabaseMetaDataKey::kInvalidBlobKey
= -1;
1432 std::string
DatabaseMetaDataKey::Encode(int64 database_id
,
1433 MetaDataType meta_data_type
) {
1434 KeyPrefix
prefix(database_id
);
1435 std::string ret
= prefix
.Encode();
1436 ret
.push_back(meta_data_type
);
1440 ObjectStoreMetaDataKey::ObjectStoreMetaDataKey()
1441 : object_store_id_(-1), meta_data_type_(0xFF) {}
1443 bool ObjectStoreMetaDataKey::Decode(StringPiece
* slice
,
1444 ObjectStoreMetaDataKey
* result
) {
1446 if (!KeyPrefix::Decode(slice
, &prefix
))
1448 DCHECK(prefix
.database_id_
);
1449 DCHECK(!prefix
.object_store_id_
);
1450 DCHECK(!prefix
.index_id_
);
1451 unsigned char type_byte
= 0;
1452 if (!DecodeByte(slice
, &type_byte
))
1454 DCHECK_EQ(type_byte
, kObjectStoreMetaDataTypeByte
);
1455 if (!DecodeVarInt(slice
, &result
->object_store_id_
))
1457 DCHECK(result
->object_store_id_
);
1458 if (!DecodeByte(slice
, &result
->meta_data_type_
))
1463 std::string
ObjectStoreMetaDataKey::Encode(int64 database_id
,
1464 int64 object_store_id
,
1465 unsigned char meta_data_type
) {
1466 KeyPrefix
prefix(database_id
);
1467 std::string ret
= prefix
.Encode();
1468 ret
.push_back(kObjectStoreMetaDataTypeByte
);
1469 EncodeVarInt(object_store_id
, &ret
);
1470 ret
.push_back(meta_data_type
);
1474 std::string
ObjectStoreMetaDataKey::EncodeMaxKey(int64 database_id
) {
1475 return Encode(database_id
,
1476 std::numeric_limits
<int64
>::max(),
1477 kObjectMetaDataTypeMaximum
);
1480 std::string
ObjectStoreMetaDataKey::EncodeMaxKey(int64 database_id
,
1481 int64 object_store_id
) {
1482 return Encode(database_id
, object_store_id
, kObjectMetaDataTypeMaximum
);
1485 int64
ObjectStoreMetaDataKey::ObjectStoreId() const {
1486 DCHECK_GE(object_store_id_
, 0);
1487 return object_store_id_
;
1489 unsigned char ObjectStoreMetaDataKey::MetaDataType() const {
1490 return meta_data_type_
;
1493 int ObjectStoreMetaDataKey::Compare(const ObjectStoreMetaDataKey
& other
) {
1494 DCHECK_GE(object_store_id_
, 0);
1495 if (int x
= CompareInts(object_store_id_
, other
.object_store_id_
))
1497 return meta_data_type_
- other
.meta_data_type_
;
1500 IndexMetaDataKey::IndexMetaDataKey()
1501 : object_store_id_(-1), index_id_(-1), meta_data_type_(0) {}
1503 bool IndexMetaDataKey::Decode(StringPiece
* slice
, IndexMetaDataKey
* result
) {
1505 if (!KeyPrefix::Decode(slice
, &prefix
))
1507 DCHECK(prefix
.database_id_
);
1508 DCHECK(!prefix
.object_store_id_
);
1509 DCHECK(!prefix
.index_id_
);
1510 unsigned char type_byte
= 0;
1511 if (!DecodeByte(slice
, &type_byte
))
1513 DCHECK_EQ(type_byte
, kIndexMetaDataTypeByte
);
1514 if (!DecodeVarInt(slice
, &result
->object_store_id_
))
1516 if (!DecodeVarInt(slice
, &result
->index_id_
))
1518 if (!DecodeByte(slice
, &result
->meta_data_type_
))
1523 std::string
IndexMetaDataKey::Encode(int64 database_id
,
1524 int64 object_store_id
,
1526 unsigned char meta_data_type
) {
1527 KeyPrefix
prefix(database_id
);
1528 std::string ret
= prefix
.Encode();
1529 ret
.push_back(kIndexMetaDataTypeByte
);
1530 EncodeVarInt(object_store_id
, &ret
);
1531 EncodeVarInt(index_id
, &ret
);
1532 EncodeByte(meta_data_type
, &ret
);
1536 std::string
IndexMetaDataKey::EncodeMaxKey(int64 database_id
,
1537 int64 object_store_id
) {
1538 return Encode(database_id
,
1540 std::numeric_limits
<int64
>::max(),
1541 kIndexMetaDataTypeMaximum
);
1544 std::string
IndexMetaDataKey::EncodeMaxKey(int64 database_id
,
1545 int64 object_store_id
,
1548 database_id
, object_store_id
, index_id
, kIndexMetaDataTypeMaximum
);
1551 int IndexMetaDataKey::Compare(const IndexMetaDataKey
& other
) {
1552 DCHECK_GE(object_store_id_
, 0);
1553 DCHECK_GE(index_id_
, 0);
1555 if (int x
= CompareInts(object_store_id_
, other
.object_store_id_
))
1557 if (int x
= CompareInts(index_id_
, other
.index_id_
))
1559 return meta_data_type_
- other
.meta_data_type_
;
1562 int64
IndexMetaDataKey::IndexId() const {
1563 DCHECK_GE(index_id_
, 0);
1567 ObjectStoreFreeListKey::ObjectStoreFreeListKey() : object_store_id_(-1) {}
1569 bool ObjectStoreFreeListKey::Decode(StringPiece
* slice
,
1570 ObjectStoreFreeListKey
* result
) {
1572 if (!KeyPrefix::Decode(slice
, &prefix
))
1574 DCHECK(prefix
.database_id_
);
1575 DCHECK(!prefix
.object_store_id_
);
1576 DCHECK(!prefix
.index_id_
);
1577 unsigned char type_byte
= 0;
1578 if (!DecodeByte(slice
, &type_byte
))
1580 DCHECK_EQ(type_byte
, kObjectStoreFreeListTypeByte
);
1581 if (!DecodeVarInt(slice
, &result
->object_store_id_
))
1586 std::string
ObjectStoreFreeListKey::Encode(int64 database_id
,
1587 int64 object_store_id
) {
1588 KeyPrefix
prefix(database_id
);
1589 std::string ret
= prefix
.Encode();
1590 ret
.push_back(kObjectStoreFreeListTypeByte
);
1591 EncodeVarInt(object_store_id
, &ret
);
1595 std::string
ObjectStoreFreeListKey::EncodeMaxKey(int64 database_id
) {
1596 return Encode(database_id
, std::numeric_limits
<int64
>::max());
1599 int64
ObjectStoreFreeListKey::ObjectStoreId() const {
1600 DCHECK_GE(object_store_id_
, 0);
1601 return object_store_id_
;
1604 int ObjectStoreFreeListKey::Compare(const ObjectStoreFreeListKey
& other
) {
1605 // TODO(jsbell): It may seem strange that we're not comparing database id's,
1606 // but that comparison will have been made earlier.
1607 // We should probably make this more clear, though...
1608 DCHECK_GE(object_store_id_
, 0);
1609 return CompareInts(object_store_id_
, other
.object_store_id_
);
1612 IndexFreeListKey::IndexFreeListKey() : object_store_id_(-1), index_id_(-1) {}
1614 bool IndexFreeListKey::Decode(StringPiece
* slice
, IndexFreeListKey
* result
) {
1616 if (!KeyPrefix::Decode(slice
, &prefix
))
1618 DCHECK(prefix
.database_id_
);
1619 DCHECK(!prefix
.object_store_id_
);
1620 DCHECK(!prefix
.index_id_
);
1621 unsigned char type_byte
= 0;
1622 if (!DecodeByte(slice
, &type_byte
))
1624 DCHECK_EQ(type_byte
, kIndexFreeListTypeByte
);
1625 if (!DecodeVarInt(slice
, &result
->object_store_id_
))
1627 if (!DecodeVarInt(slice
, &result
->index_id_
))
1632 std::string
IndexFreeListKey::Encode(int64 database_id
,
1633 int64 object_store_id
,
1635 KeyPrefix
prefix(database_id
);
1636 std::string ret
= prefix
.Encode();
1637 ret
.push_back(kIndexFreeListTypeByte
);
1638 EncodeVarInt(object_store_id
, &ret
);
1639 EncodeVarInt(index_id
, &ret
);
1643 std::string
IndexFreeListKey::EncodeMaxKey(int64 database_id
,
1644 int64 object_store_id
) {
1646 database_id
, object_store_id
, std::numeric_limits
<int64
>::max());
1649 int IndexFreeListKey::Compare(const IndexFreeListKey
& other
) {
1650 DCHECK_GE(object_store_id_
, 0);
1651 DCHECK_GE(index_id_
, 0);
1652 if (int x
= CompareInts(object_store_id_
, other
.object_store_id_
))
1654 return CompareInts(index_id_
, other
.index_id_
);
1657 int64
IndexFreeListKey::ObjectStoreId() const {
1658 DCHECK_GE(object_store_id_
, 0);
1659 return object_store_id_
;
1662 int64
IndexFreeListKey::IndexId() const {
1663 DCHECK_GE(index_id_
, 0);
1667 // TODO(jsbell): We never use this to look up object store ids,
1668 // because a mapping is kept in the IndexedDBDatabase. Can the
1669 // mapping become unreliable? Can we remove this?
1670 bool ObjectStoreNamesKey::Decode(StringPiece
* slice
,
1671 ObjectStoreNamesKey
* result
) {
1673 if (!KeyPrefix::Decode(slice
, &prefix
))
1675 DCHECK(prefix
.database_id_
);
1676 DCHECK(!prefix
.object_store_id_
);
1677 DCHECK(!prefix
.index_id_
);
1678 unsigned char type_byte
= 0;
1679 if (!DecodeByte(slice
, &type_byte
))
1681 DCHECK_EQ(type_byte
, kObjectStoreNamesTypeByte
);
1682 if (!DecodeStringWithLength(slice
, &result
->object_store_name_
))
1687 std::string
ObjectStoreNamesKey::Encode(
1689 const base::string16
& object_store_name
) {
1690 KeyPrefix
prefix(database_id
);
1691 std::string ret
= prefix
.Encode();
1692 ret
.push_back(kObjectStoreNamesTypeByte
);
1693 EncodeStringWithLength(object_store_name
, &ret
);
1697 int ObjectStoreNamesKey::Compare(const ObjectStoreNamesKey
& other
) {
1698 return object_store_name_
.compare(other
.object_store_name_
);
1701 IndexNamesKey::IndexNamesKey() : object_store_id_(-1) {}
1703 // TODO(jsbell): We never use this to look up index ids, because a mapping
1704 // is kept at a higher level.
1705 bool IndexNamesKey::Decode(StringPiece
* slice
, IndexNamesKey
* result
) {
1707 if (!KeyPrefix::Decode(slice
, &prefix
))
1709 DCHECK(prefix
.database_id_
);
1710 DCHECK(!prefix
.object_store_id_
);
1711 DCHECK(!prefix
.index_id_
);
1712 unsigned char type_byte
= 0;
1713 if (!DecodeByte(slice
, &type_byte
))
1715 DCHECK_EQ(type_byte
, kIndexNamesKeyTypeByte
);
1716 if (!DecodeVarInt(slice
, &result
->object_store_id_
))
1718 if (!DecodeStringWithLength(slice
, &result
->index_name_
))
1723 std::string
IndexNamesKey::Encode(int64 database_id
,
1724 int64 object_store_id
,
1725 const base::string16
& index_name
) {
1726 KeyPrefix
prefix(database_id
);
1727 std::string ret
= prefix
.Encode();
1728 ret
.push_back(kIndexNamesKeyTypeByte
);
1729 EncodeVarInt(object_store_id
, &ret
);
1730 EncodeStringWithLength(index_name
, &ret
);
1734 int IndexNamesKey::Compare(const IndexNamesKey
& other
) {
1735 DCHECK_GE(object_store_id_
, 0);
1736 if (int x
= CompareInts(object_store_id_
, other
.object_store_id_
))
1738 return index_name_
.compare(other
.index_name_
);
1741 ObjectStoreDataKey::ObjectStoreDataKey() {}
1742 ObjectStoreDataKey::~ObjectStoreDataKey() {}
1744 bool ObjectStoreDataKey::Decode(StringPiece
* slice
,
1745 ObjectStoreDataKey
* result
) {
1747 if (!KeyPrefix::Decode(slice
, &prefix
))
1749 DCHECK(prefix
.database_id_
);
1750 DCHECK(prefix
.object_store_id_
);
1751 DCHECK_EQ(prefix
.index_id_
, kSpecialIndexNumber
);
1752 if (!ExtractEncodedIDBKey(slice
, &result
->encoded_user_key_
))
1757 std::string
ObjectStoreDataKey::Encode(int64 database_id
,
1758 int64 object_store_id
,
1759 const std::string encoded_user_key
) {
1760 KeyPrefix
prefix(KeyPrefix::CreateWithSpecialIndex(
1761 database_id
, object_store_id
, kSpecialIndexNumber
));
1762 std::string ret
= prefix
.Encode();
1763 ret
.append(encoded_user_key
);
1768 std::string
ObjectStoreDataKey::Encode(int64 database_id
,
1769 int64 object_store_id
,
1770 const IndexedDBKey
& user_key
) {
1771 std::string encoded_key
;
1772 EncodeIDBKey(user_key
, &encoded_key
);
1773 return Encode(database_id
, object_store_id
, encoded_key
);
1776 scoped_ptr
<IndexedDBKey
> ObjectStoreDataKey::user_key() const {
1777 scoped_ptr
<IndexedDBKey
> key
;
1778 StringPiece
slice(encoded_user_key_
);
1779 if (!DecodeIDBKey(&slice
, &key
)) {
1780 // TODO(jsbell): Return error.
1785 const int64
ObjectStoreDataKey::kSpecialIndexNumber
= kObjectStoreDataIndexId
;
1787 ExistsEntryKey::ExistsEntryKey() {}
1788 ExistsEntryKey::~ExistsEntryKey() {}
1790 bool ExistsEntryKey::Decode(StringPiece
* slice
, ExistsEntryKey
* result
) {
1792 if (!KeyPrefix::Decode(slice
, &prefix
))
1794 DCHECK(prefix
.database_id_
);
1795 DCHECK(prefix
.object_store_id_
);
1796 DCHECK_EQ(prefix
.index_id_
, kSpecialIndexNumber
);
1797 if (!ExtractEncodedIDBKey(slice
, &result
->encoded_user_key_
))
1802 std::string
ExistsEntryKey::Encode(int64 database_id
,
1803 int64 object_store_id
,
1804 const std::string
& encoded_key
) {
1805 KeyPrefix
prefix(KeyPrefix::CreateWithSpecialIndex(
1806 database_id
, object_store_id
, kSpecialIndexNumber
));
1807 std::string ret
= prefix
.Encode();
1808 ret
.append(encoded_key
);
1812 std::string
ExistsEntryKey::Encode(int64 database_id
,
1813 int64 object_store_id
,
1814 const IndexedDBKey
& user_key
) {
1815 std::string encoded_key
;
1816 EncodeIDBKey(user_key
, &encoded_key
);
1817 return Encode(database_id
, object_store_id
, encoded_key
);
1820 scoped_ptr
<IndexedDBKey
> ExistsEntryKey::user_key() const {
1821 scoped_ptr
<IndexedDBKey
> key
;
1822 StringPiece
slice(encoded_user_key_
);
1823 if (!DecodeIDBKey(&slice
, &key
)) {
1824 // TODO(jsbell): Return error.
1829 const int64
ExistsEntryKey::kSpecialIndexNumber
= kExistsEntryIndexId
;
1831 bool BlobEntryKey::Decode(StringPiece
* slice
, BlobEntryKey
* result
) {
1833 if (!KeyPrefix::Decode(slice
, &prefix
))
1835 DCHECK(prefix
.database_id_
);
1836 DCHECK(prefix
.object_store_id_
);
1837 DCHECK_EQ(prefix
.index_id_
, kSpecialIndexNumber
);
1839 if (!ExtractEncodedIDBKey(slice
, &result
->encoded_user_key_
))
1841 result
->database_id_
= prefix
.database_id_
;
1842 result
->object_store_id_
= prefix
.object_store_id_
;
1847 bool BlobEntryKey::FromObjectStoreDataKey(StringPiece
* slice
,
1848 BlobEntryKey
* result
) {
1850 if (!KeyPrefix::Decode(slice
, &prefix
))
1852 DCHECK(prefix
.database_id_
);
1853 DCHECK(prefix
.object_store_id_
);
1854 DCHECK_EQ(prefix
.index_id_
, ObjectStoreDataKey::kSpecialIndexNumber
);
1856 if (!ExtractEncodedIDBKey(slice
, &result
->encoded_user_key_
))
1858 result
->database_id_
= prefix
.database_id_
;
1859 result
->object_store_id_
= prefix
.object_store_id_
;
1863 std::string
BlobEntryKey::ReencodeToObjectStoreDataKey(StringPiece
* slice
) {
1864 // TODO(ericu): We could be more efficient here, since the suffix is the same.
1866 if (!Decode(slice
, &key
))
1867 return std::string();
1869 return ObjectStoreDataKey::Encode(
1870 key
.database_id_
, key
.object_store_id_
, key
.encoded_user_key_
);
1873 std::string
BlobEntryKey::EncodeMinKeyForObjectStore(int64 database_id
,
1874 int64 object_store_id
) {
1875 // Our implied encoded_user_key_ here is empty, the lowest possible key.
1876 return Encode(database_id
, object_store_id
, std::string());
1879 std::string
BlobEntryKey::EncodeStopKeyForObjectStore(int64 database_id
,
1880 int64 object_store_id
) {
1881 DCHECK(KeyPrefix::ValidIds(database_id
, object_store_id
));
1882 KeyPrefix
prefix(KeyPrefix::CreateWithSpecialIndex(
1883 database_id
, object_store_id
, kSpecialIndexNumber
+ 1));
1884 return prefix
.Encode();
1887 std::string
BlobEntryKey::Encode() const {
1888 DCHECK(!encoded_user_key_
.empty());
1889 return Encode(database_id_
, object_store_id_
, encoded_user_key_
);
1892 std::string
BlobEntryKey::Encode(int64 database_id
,
1893 int64 object_store_id
,
1894 const IndexedDBKey
& user_key
) {
1895 std::string encoded_key
;
1896 EncodeIDBKey(user_key
, &encoded_key
);
1897 return Encode(database_id
, object_store_id
, encoded_key
);
1900 std::string
BlobEntryKey::Encode(int64 database_id
,
1901 int64 object_store_id
,
1902 const std::string
& encoded_user_key
) {
1903 DCHECK(KeyPrefix::ValidIds(database_id
, object_store_id
));
1904 KeyPrefix
prefix(KeyPrefix::CreateWithSpecialIndex(
1905 database_id
, object_store_id
, kSpecialIndexNumber
));
1906 return prefix
.Encode() + encoded_user_key
;
1909 const int64
BlobEntryKey::kSpecialIndexNumber
= kBlobEntryIndexId
;
1911 IndexDataKey::IndexDataKey()
1913 object_store_id_(-1),
1915 sequence_number_(-1) {}
1917 IndexDataKey::~IndexDataKey() {}
1919 bool IndexDataKey::Decode(StringPiece
* slice
, IndexDataKey
* result
) {
1921 if (!KeyPrefix::Decode(slice
, &prefix
))
1923 DCHECK(prefix
.database_id_
);
1924 DCHECK(prefix
.object_store_id_
);
1925 DCHECK_GE(prefix
.index_id_
, kMinimumIndexId
);
1926 result
->database_id_
= prefix
.database_id_
;
1927 result
->object_store_id_
= prefix
.object_store_id_
;
1928 result
->index_id_
= prefix
.index_id_
;
1929 result
->sequence_number_
= -1;
1930 result
->encoded_primary_key_
= MinIDBKey();
1932 if (!ExtractEncodedIDBKey(slice
, &result
->encoded_user_key_
))
1935 // [optional] sequence number
1938 if (!DecodeVarInt(slice
, &result
->sequence_number_
))
1941 // [optional] primary key
1944 if (!ExtractEncodedIDBKey(slice
, &result
->encoded_primary_key_
))
1949 std::string
IndexDataKey::Encode(int64 database_id
,
1950 int64 object_store_id
,
1952 const std::string
& encoded_user_key
,
1953 const std::string
& encoded_primary_key
,
1954 int64 sequence_number
) {
1955 KeyPrefix
prefix(database_id
, object_store_id
, index_id
);
1956 std::string ret
= prefix
.Encode();
1957 ret
.append(encoded_user_key
);
1958 EncodeVarInt(sequence_number
, &ret
);
1959 ret
.append(encoded_primary_key
);
1963 std::string
IndexDataKey::Encode(int64 database_id
,
1964 int64 object_store_id
,
1966 const IndexedDBKey
& user_key
) {
1967 std::string encoded_key
;
1968 EncodeIDBKey(user_key
, &encoded_key
);
1970 database_id
, object_store_id
, index_id
, encoded_key
, MinIDBKey(), 0);
1973 std::string
IndexDataKey::Encode(int64 database_id
,
1974 int64 object_store_id
,
1976 const IndexedDBKey
& user_key
,
1977 const IndexedDBKey
& user_primary_key
) {
1978 std::string encoded_key
;
1979 EncodeIDBKey(user_key
, &encoded_key
);
1980 std::string encoded_primary_key
;
1981 EncodeIDBKey(user_primary_key
, &encoded_primary_key
);
1982 return Encode(database_id
,
1986 encoded_primary_key
,
1990 std::string
IndexDataKey::EncodeMinKey(int64 database_id
,
1991 int64 object_store_id
,
1994 database_id
, object_store_id
, index_id
, MinIDBKey(), MinIDBKey(), 0);
1997 std::string
IndexDataKey::EncodeMaxKey(int64 database_id
,
1998 int64 object_store_id
,
2000 return Encode(database_id
,
2005 std::numeric_limits
<int64
>::max());
2008 int64
IndexDataKey::DatabaseId() const {
2009 DCHECK_GE(database_id_
, 0);
2010 return database_id_
;
2013 int64
IndexDataKey::ObjectStoreId() const {
2014 DCHECK_GE(object_store_id_
, 0);
2015 return object_store_id_
;
2018 int64
IndexDataKey::IndexId() const {
2019 DCHECK_GE(index_id_
, 0);
2023 scoped_ptr
<IndexedDBKey
> IndexDataKey::user_key() const {
2024 scoped_ptr
<IndexedDBKey
> key
;
2025 StringPiece
slice(encoded_user_key_
);
2026 if (!DecodeIDBKey(&slice
, &key
)) {
2027 // TODO(jsbell): Return error.
2032 scoped_ptr
<IndexedDBKey
> IndexDataKey::primary_key() const {
2033 scoped_ptr
<IndexedDBKey
> key
;
2034 StringPiece
slice(encoded_primary_key_
);
2035 if (!DecodeIDBKey(&slice
, &key
)) {
2036 // TODO(jsbell): Return error.
2041 } // namespace content