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 using base::StringPiece
;
165 using blink::WebIDBKeyType
;
166 using blink::WebIDBKeyTypeArray
;
167 using blink::WebIDBKeyTypeBinary
;
168 using blink::WebIDBKeyTypeDate
;
169 using blink::WebIDBKeyTypeInvalid
;
170 using blink::WebIDBKeyTypeMin
;
171 using blink::WebIDBKeyTypeNull
;
172 using blink::WebIDBKeyTypeNumber
;
173 using blink::WebIDBKeyTypeString
;
174 using blink::WebIDBKeyPathType
;
175 using blink::WebIDBKeyPathTypeArray
;
176 using blink::WebIDBKeyPathTypeNull
;
177 using blink::WebIDBKeyPathTypeString
;
181 // As most of the IndexedDBKeys and encoded values are short, we
182 // initialize some std::vectors with a default inline buffer size to reduce
183 // the memory re-allocations when the std::vectors are appended.
184 static const size_t kDefaultInlineBufferSize
= 32;
186 static const unsigned char kIndexedDBKeyNullTypeByte
= 0;
187 static const unsigned char kIndexedDBKeyStringTypeByte
= 1;
188 static const unsigned char kIndexedDBKeyDateTypeByte
= 2;
189 static const unsigned char kIndexedDBKeyNumberTypeByte
= 3;
190 static const unsigned char kIndexedDBKeyArrayTypeByte
= 4;
191 static const unsigned char kIndexedDBKeyMinKeyTypeByte
= 5;
192 static const unsigned char kIndexedDBKeyBinaryTypeByte
= 6;
194 static const unsigned char kIndexedDBKeyPathTypeCodedByte1
= 0;
195 static const unsigned char kIndexedDBKeyPathTypeCodedByte2
= 0;
197 static const unsigned char kObjectStoreDataIndexId
= 1;
198 static const unsigned char kExistsEntryIndexId
= 2;
199 static const unsigned char kBlobEntryIndexId
= 3;
201 static const unsigned char kSchemaVersionTypeByte
= 0;
202 static const unsigned char kMaxDatabaseIdTypeByte
= 1;
203 static const unsigned char kDataVersionTypeByte
= 2;
204 static const unsigned char kBlobJournalTypeByte
= 3;
205 static const unsigned char kLiveBlobJournalTypeByte
= 4;
206 static const unsigned char kMaxSimpleGlobalMetaDataTypeByte
=
207 5; // Insert before this and increment.
208 static const unsigned char kDatabaseFreeListTypeByte
= 100;
209 static const unsigned char kDatabaseNameTypeByte
= 201;
211 static const unsigned char kObjectStoreMetaDataTypeByte
= 50;
212 static const unsigned char kIndexMetaDataTypeByte
= 100;
213 static const unsigned char kObjectStoreFreeListTypeByte
= 150;
214 static const unsigned char kIndexFreeListTypeByte
= 151;
215 static const unsigned char kObjectStoreNamesTypeByte
= 200;
216 static const unsigned char kIndexNamesKeyTypeByte
= 201;
218 static const unsigned char kObjectMetaDataTypeMaximum
= 255;
219 static const unsigned char kIndexMetaDataTypeMaximum
= 255;
221 const unsigned char kMinimumIndexId
= 30;
223 inline void EncodeIntSafely(int64 nParam
, int64 max
, std::string
* into
) {
224 DCHECK_LE(nParam
, max
);
225 return EncodeInt(nParam
, into
);
228 std::string
MaxIDBKey() {
230 EncodeByte(kIndexedDBKeyNullTypeByte
, &ret
);
234 std::string
MinIDBKey() {
236 EncodeByte(kIndexedDBKeyMinKeyTypeByte
, &ret
);
240 void EncodeByte(unsigned char value
, std::string
* into
) {
241 into
->push_back(value
);
244 void EncodeBool(bool value
, std::string
* into
) {
245 into
->push_back(value
? 1 : 0);
248 void EncodeInt(int64 value
, std::string
* into
) {
250 // Exercised by unit tests in debug only.
253 uint64 n
= static_cast<uint64
>(value
);
262 void EncodeVarInt(int64 value
, std::string
* into
) {
264 // Exercised by unit tests in debug only.
267 uint64 n
= static_cast<uint64
>(value
);
270 unsigned char c
= n
& 0x7f;
278 void EncodeString(const base::string16
& value
, std::string
* into
) {
281 // Backing store is UTF-16BE, convert from host endianness.
282 size_t length
= value
.length();
283 size_t current
= into
->size();
284 into
->resize(into
->size() + length
* sizeof(base::char16
));
286 const base::char16
* src
= value
.c_str();
288 reinterpret_cast<base::char16
*>(&*into
->begin() + current
);
289 for (unsigned i
= 0; i
< length
; ++i
)
290 *dst
++ = htons(*src
++);
293 void EncodeBinary(const std::string
& value
, std::string
* into
) {
294 EncodeVarInt(value
.length(), into
);
295 into
->append(value
.begin(), value
.end());
296 DCHECK(into
->size() >= value
.size());
299 void EncodeStringWithLength(const base::string16
& value
, std::string
* into
) {
300 EncodeVarInt(value
.length(), into
);
301 EncodeString(value
, into
);
304 void EncodeDouble(double value
, std::string
* into
) {
305 // This always has host endianness.
306 const char* p
= reinterpret_cast<char*>(&value
);
307 into
->insert(into
->end(), p
, p
+ sizeof(value
));
310 void EncodeIDBKey(const IndexedDBKey
& value
, std::string
* into
) {
311 size_t previous_size
= into
->size();
312 DCHECK(value
.IsValid());
313 switch (value
.type()) {
314 case WebIDBKeyTypeArray
: {
315 EncodeByte(kIndexedDBKeyArrayTypeByte
, into
);
316 size_t length
= value
.array().size();
317 EncodeVarInt(length
, into
);
318 for (size_t i
= 0; i
< length
; ++i
)
319 EncodeIDBKey(value
.array()[i
], into
);
320 DCHECK_GT(into
->size(), previous_size
);
323 case WebIDBKeyTypeBinary
:
324 EncodeByte(kIndexedDBKeyBinaryTypeByte
, into
);
325 EncodeBinary(value
.binary(), into
);
326 DCHECK_GT(into
->size(), previous_size
);
328 case WebIDBKeyTypeString
:
329 EncodeByte(kIndexedDBKeyStringTypeByte
, into
);
330 EncodeStringWithLength(value
.string(), into
);
331 DCHECK_GT(into
->size(), previous_size
);
333 case WebIDBKeyTypeDate
:
334 EncodeByte(kIndexedDBKeyDateTypeByte
, into
);
335 EncodeDouble(value
.date(), into
);
336 DCHECK_EQ(9u, static_cast<size_t>(into
->size() - previous_size
));
338 case WebIDBKeyTypeNumber
:
339 EncodeByte(kIndexedDBKeyNumberTypeByte
, into
);
340 EncodeDouble(value
.number(), into
);
341 DCHECK_EQ(9u, static_cast<size_t>(into
->size() - previous_size
));
343 case WebIDBKeyTypeNull
:
344 case WebIDBKeyTypeInvalid
:
345 case WebIDBKeyTypeMin
:
348 EncodeByte(kIndexedDBKeyNullTypeByte
, into
);
353 void EncodeIDBKeyPath(const IndexedDBKeyPath
& value
, std::string
* into
) {
354 // May be typed, or may be a raw string. An invalid leading
355 // byte is used to identify typed coding. New records are
356 // always written as typed.
357 EncodeByte(kIndexedDBKeyPathTypeCodedByte1
, into
);
358 EncodeByte(kIndexedDBKeyPathTypeCodedByte2
, into
);
359 EncodeByte(static_cast<char>(value
.type()), into
);
360 switch (value
.type()) {
361 case WebIDBKeyPathTypeNull
:
363 case WebIDBKeyPathTypeString
: {
364 EncodeStringWithLength(value
.string(), into
);
367 case WebIDBKeyPathTypeArray
: {
368 const std::vector
<base::string16
>& array
= value
.array();
369 size_t count
= array
.size();
370 EncodeVarInt(count
, into
);
371 for (size_t i
= 0; i
< count
; ++i
) {
372 EncodeStringWithLength(array
[i
], into
);
379 void EncodeBlobJournal(const BlobJournalType
& journal
, std::string
* into
) {
380 BlobJournalType::const_iterator iter
;
381 for (iter
= journal
.begin(); iter
!= journal
.end(); ++iter
) {
382 EncodeVarInt(iter
->first
, into
);
383 EncodeVarInt(iter
->second
, into
);
387 bool DecodeByte(StringPiece
* slice
, unsigned char* value
) {
391 *value
= (*slice
)[0];
392 slice
->remove_prefix(1);
396 bool DecodeBool(StringPiece
* slice
, bool* value
) {
400 *value
= !!(*slice
)[0];
401 slice
->remove_prefix(1);
405 bool DecodeInt(StringPiece
* slice
, int64
* value
) {
409 StringPiece::const_iterator it
= slice
->begin();
412 while (it
!= slice
->end()) {
413 unsigned char c
= *it
++;
414 ret
|= static_cast<int64
>(c
) << shift
;
418 slice
->remove_prefix(it
- slice
->begin());
422 bool DecodeVarInt(StringPiece
* slice
, int64
* value
) {
426 StringPiece::const_iterator it
= slice
->begin();
430 if (it
== slice
->end())
433 unsigned char c
= *it
;
434 ret
|= static_cast<int64
>(c
& 0x7f) << shift
;
436 } while (*it
++ & 0x80);
438 slice
->remove_prefix(it
- slice
->begin());
442 bool DecodeString(StringPiece
* slice
, base::string16
* value
) {
443 if (slice
->empty()) {
448 // Backing store is UTF-16BE, convert to host endianness.
449 DCHECK(!(slice
->size() % sizeof(base::char16
)));
450 size_t length
= slice
->size() / sizeof(base::char16
);
451 base::string16 decoded
;
452 decoded
.reserve(length
);
453 const base::char16
* encoded
=
454 reinterpret_cast<const base::char16
*>(slice
->begin());
455 for (unsigned i
= 0; i
< length
; ++i
)
456 decoded
.push_back(ntohs(*encoded
++));
459 slice
->remove_prefix(length
* sizeof(base::char16
));
463 bool DecodeStringWithLength(StringPiece
* slice
, base::string16
* value
) {
468 if (!DecodeVarInt(slice
, &length
) || length
< 0)
470 size_t bytes
= length
* sizeof(base::char16
);
471 if (slice
->size() < bytes
)
474 StringPiece
subpiece(slice
->begin(), bytes
);
475 slice
->remove_prefix(bytes
);
476 if (!DecodeString(&subpiece
, value
))
482 bool DecodeBinary(StringPiece
* slice
, std::string
* value
) {
487 if (!DecodeVarInt(slice
, &length
) || length
< 0)
489 size_t size
= length
;
490 if (slice
->size() < size
)
493 value
->assign(slice
->begin(), size
);
494 slice
->remove_prefix(size
);
498 bool DecodeIDBKey(StringPiece
* slice
, scoped_ptr
<IndexedDBKey
>* value
) {
502 unsigned char type
= (*slice
)[0];
503 slice
->remove_prefix(1);
506 case kIndexedDBKeyNullTypeByte
:
507 *value
= make_scoped_ptr(new IndexedDBKey());
510 case kIndexedDBKeyArrayTypeByte
: {
512 if (!DecodeVarInt(slice
, &length
) || length
< 0)
514 IndexedDBKey::KeyArray array
;
516 scoped_ptr
<IndexedDBKey
> key
;
517 if (!DecodeIDBKey(slice
, &key
))
519 array
.push_back(*key
);
521 *value
= make_scoped_ptr(new IndexedDBKey(array
));
524 case kIndexedDBKeyBinaryTypeByte
: {
526 if (!DecodeBinary(slice
, &binary
))
528 *value
= make_scoped_ptr(new IndexedDBKey(binary
));
531 case kIndexedDBKeyStringTypeByte
: {
533 if (!DecodeStringWithLength(slice
, &s
))
535 *value
= make_scoped_ptr(new IndexedDBKey(s
));
538 case kIndexedDBKeyDateTypeByte
: {
540 if (!DecodeDouble(slice
, &d
))
542 *value
= make_scoped_ptr(new IndexedDBKey(d
, WebIDBKeyTypeDate
));
545 case kIndexedDBKeyNumberTypeByte
: {
547 if (!DecodeDouble(slice
, &d
))
549 *value
= make_scoped_ptr(new IndexedDBKey(d
, WebIDBKeyTypeNumber
));
558 bool DecodeDouble(StringPiece
* slice
, double* value
) {
559 if (slice
->size() < sizeof(*value
))
562 memcpy(value
, slice
->begin(), sizeof(*value
));
563 slice
->remove_prefix(sizeof(*value
));
567 bool DecodeIDBKeyPath(StringPiece
* slice
, IndexedDBKeyPath
* value
) {
568 // May be typed, or may be a raw string. An invalid leading
569 // byte sequence is used to identify typed coding. New records are
570 // always written as typed.
571 if (slice
->size() < 3 || (*slice
)[0] != kIndexedDBKeyPathTypeCodedByte1
||
572 (*slice
)[1] != kIndexedDBKeyPathTypeCodedByte2
) {
574 if (!DecodeString(slice
, &s
))
576 *value
= IndexedDBKeyPath(s
);
580 slice
->remove_prefix(2);
581 DCHECK(!slice
->empty());
582 WebIDBKeyPathType type
= static_cast<WebIDBKeyPathType
>((*slice
)[0]);
583 slice
->remove_prefix(1);
586 case WebIDBKeyPathTypeNull
:
587 DCHECK(slice
->empty());
588 *value
= IndexedDBKeyPath();
590 case WebIDBKeyPathTypeString
: {
591 base::string16 string
;
592 if (!DecodeStringWithLength(slice
, &string
))
594 DCHECK(slice
->empty());
595 *value
= IndexedDBKeyPath(string
);
598 case WebIDBKeyPathTypeArray
: {
599 std::vector
<base::string16
> array
;
601 if (!DecodeVarInt(slice
, &count
))
605 base::string16 string
;
606 if (!DecodeStringWithLength(slice
, &string
))
608 array
.push_back(string
);
610 DCHECK(slice
->empty());
611 *value
= IndexedDBKeyPath(array
);
619 bool DecodeBlobJournal(StringPiece
* slice
, BlobJournalType
* journal
) {
620 BlobJournalType output
;
621 while (!slice
->empty()) {
622 int64 database_id
= -1;
624 if (!DecodeVarInt(slice
, &database_id
))
626 if (!KeyPrefix::IsValidDatabaseId(database_id
))
628 if (!DecodeVarInt(slice
, &blob_key
))
630 if (!DatabaseMetaDataKey::IsValidBlobKey(blob_key
) &&
631 (blob_key
!= DatabaseMetaDataKey::kAllBlobsKey
)) {
634 output
.push_back(std::make_pair(database_id
, blob_key
));
636 journal
->swap(output
);
640 bool ConsumeEncodedIDBKey(StringPiece
* slice
) {
641 unsigned char type
= (*slice
)[0];
642 slice
->remove_prefix(1);
645 case kIndexedDBKeyNullTypeByte
:
646 case kIndexedDBKeyMinKeyTypeByte
:
648 case kIndexedDBKeyArrayTypeByte
: {
650 if (!DecodeVarInt(slice
, &length
))
653 if (!ConsumeEncodedIDBKey(slice
))
658 case kIndexedDBKeyBinaryTypeByte
: {
660 if (!DecodeVarInt(slice
, &length
) || length
< 0)
662 if (slice
->size() < static_cast<size_t>(length
))
664 slice
->remove_prefix(length
);
667 case kIndexedDBKeyStringTypeByte
: {
669 if (!DecodeVarInt(slice
, &length
) || length
< 0)
671 if (slice
->size() < static_cast<size_t>(length
) * sizeof(base::char16
))
673 slice
->remove_prefix(length
* sizeof(base::char16
));
676 case kIndexedDBKeyDateTypeByte
:
677 case kIndexedDBKeyNumberTypeByte
:
678 if (slice
->size() < sizeof(double))
680 slice
->remove_prefix(sizeof(double));
687 bool ExtractEncodedIDBKey(StringPiece
* slice
, std::string
* result
) {
688 const char* start
= slice
->begin();
689 if (!ConsumeEncodedIDBKey(slice
))
693 result
->assign(start
, slice
->begin());
697 static WebIDBKeyType
KeyTypeByteToKeyType(unsigned char type
) {
699 case kIndexedDBKeyNullTypeByte
:
700 return WebIDBKeyTypeInvalid
;
701 case kIndexedDBKeyArrayTypeByte
:
702 return WebIDBKeyTypeArray
;
703 case kIndexedDBKeyBinaryTypeByte
:
704 return WebIDBKeyTypeBinary
;
705 case kIndexedDBKeyStringTypeByte
:
706 return WebIDBKeyTypeString
;
707 case kIndexedDBKeyDateTypeByte
:
708 return WebIDBKeyTypeDate
;
709 case kIndexedDBKeyNumberTypeByte
:
710 return WebIDBKeyTypeNumber
;
711 case kIndexedDBKeyMinKeyTypeByte
:
712 return WebIDBKeyTypeMin
;
716 return WebIDBKeyTypeInvalid
;
719 int CompareEncodedStringsWithLength(StringPiece
* slice1
,
723 if (!DecodeVarInt(slice1
, &len1
) || !DecodeVarInt(slice2
, &len2
)) {
729 if (len1
< 0 || len2
< 0) {
733 DCHECK_GE(slice1
->size(), len1
* sizeof(base::char16
));
734 DCHECK_GE(slice2
->size(), len2
* sizeof(base::char16
));
735 if (slice1
->size() < len1
* sizeof(base::char16
) ||
736 slice2
->size() < len2
* sizeof(base::char16
)) {
741 // Extract the string data, and advance the passed slices.
742 StringPiece
string1(slice1
->begin(), len1
* sizeof(base::char16
));
743 StringPiece
string2(slice2
->begin(), len2
* sizeof(base::char16
));
744 slice1
->remove_prefix(len1
* sizeof(base::char16
));
745 slice2
->remove_prefix(len2
* sizeof(base::char16
));
748 // Strings are UTF-16BE encoded, so a simple memcmp is sufficient.
749 return string1
.compare(string2
);
752 int CompareEncodedBinary(StringPiece
* slice1
,
756 if (!DecodeVarInt(slice1
, &len1
) || !DecodeVarInt(slice2
, &len2
)) {
762 if (len1
< 0 || len2
< 0) {
769 DCHECK_GE(slice1
->size(), size1
);
770 DCHECK_GE(slice2
->size(), size2
);
771 if (slice1
->size() < size1
|| slice2
->size() < size2
) {
776 // Extract the binary data, and advance the passed slices.
777 StringPiece
binary1(slice1
->begin(), size1
);
778 StringPiece
binary2(slice2
->begin(), size2
);
779 slice1
->remove_prefix(size1
);
780 slice2
->remove_prefix(size2
);
783 // This is the same as a memcmp()
784 return binary1
.compare(binary2
);
787 static int CompareInts(int64 a
, int64 b
) {
789 // Exercised by unit tests in debug only.
801 static inline int CompareSizes(size_t a
, size_t b
) {
809 static int CompareTypes(WebIDBKeyType a
, WebIDBKeyType b
) { return b
- a
; }
811 int CompareEncodedIDBKeys(StringPiece
* slice_a
,
812 StringPiece
* slice_b
,
814 DCHECK(!slice_a
->empty());
815 DCHECK(!slice_b
->empty());
817 unsigned char type_a
= (*slice_a
)[0];
818 unsigned char type_b
= (*slice_b
)[0];
819 slice_a
->remove_prefix(1);
820 slice_b
->remove_prefix(1);
822 if (int x
= CompareTypes(KeyTypeByteToKeyType(type_a
),
823 KeyTypeByteToKeyType(type_b
)))
827 case kIndexedDBKeyNullTypeByte
:
828 case kIndexedDBKeyMinKeyTypeByte
:
829 // Null type or max type; no payload to compare.
831 case kIndexedDBKeyArrayTypeByte
: {
832 int64 length_a
, length_b
;
833 if (!DecodeVarInt(slice_a
, &length_a
) ||
834 !DecodeVarInt(slice_b
, &length_b
)) {
838 for (int64 i
= 0; i
< length_a
&& i
< length_b
; ++i
) {
839 int result
= CompareEncodedIDBKeys(slice_a
, slice_b
, ok
);
843 return length_a
- length_b
;
845 case kIndexedDBKeyBinaryTypeByte
:
846 return CompareEncodedBinary(slice_a
, slice_b
, ok
);
847 case kIndexedDBKeyStringTypeByte
:
848 return CompareEncodedStringsWithLength(slice_a
, slice_b
, ok
);
849 case kIndexedDBKeyDateTypeByte
:
850 case kIndexedDBKeyNumberTypeByte
: {
852 if (!DecodeDouble(slice_a
, &d
) || !DecodeDouble(slice_b
, &e
)) {
870 template <typename KeyType
>
871 int Compare(const StringPiece
& a
,
872 const StringPiece
& b
,
873 bool only_compare_index_keys
,
878 StringPiece
slice_a(a
);
879 if (!KeyType::Decode(&slice_a
, &key_a
)) {
883 StringPiece
slice_b(b
);
884 if (!KeyType::Decode(&slice_b
, &key_b
)) {
890 return key_a
.Compare(key_b
);
893 template <typename KeyType
>
894 int CompareSuffix(StringPiece
* a
,
896 bool only_compare_index_keys
,
903 int CompareSuffix
<ExistsEntryKey
>(StringPiece
* slice_a
,
904 StringPiece
* slice_b
,
905 bool only_compare_index_keys
,
907 DCHECK(!slice_a
->empty());
908 DCHECK(!slice_b
->empty());
909 return CompareEncodedIDBKeys(slice_a
, slice_b
, ok
);
913 int CompareSuffix
<ObjectStoreDataKey
>(StringPiece
* slice_a
,
914 StringPiece
* slice_b
,
915 bool only_compare_index_keys
,
917 return CompareEncodedIDBKeys(slice_a
, slice_b
, ok
);
921 int CompareSuffix
<BlobEntryKey
>(StringPiece
* slice_a
,
922 StringPiece
* slice_b
,
923 bool only_compare_index_keys
,
925 return CompareEncodedIDBKeys(slice_a
, slice_b
, ok
);
929 int CompareSuffix
<IndexDataKey
>(StringPiece
* slice_a
,
930 StringPiece
* slice_b
,
931 bool only_compare_index_keys
,
934 int result
= CompareEncodedIDBKeys(slice_a
, slice_b
, ok
);
937 if (only_compare_index_keys
)
940 // sequence number [optional]
941 int64 sequence_number_a
= -1;
942 int64 sequence_number_b
= -1;
943 if (!slice_a
->empty() && !DecodeVarInt(slice_a
, &sequence_number_a
))
945 if (!slice_b
->empty() && !DecodeVarInt(slice_b
, &sequence_number_b
))
948 if (slice_a
->empty() || slice_b
->empty())
949 return CompareSizes(slice_a
->size(), slice_b
->size());
951 // primary key [optional]
952 result
= CompareEncodedIDBKeys(slice_a
, slice_b
, ok
);
956 return CompareInts(sequence_number_a
, sequence_number_b
);
959 int Compare(const StringPiece
& a
,
960 const StringPiece
& b
,
961 bool only_compare_index_keys
,
963 StringPiece
slice_a(a
);
964 StringPiece
slice_b(b
);
967 bool ok_a
= KeyPrefix::Decode(&slice_a
, &prefix_a
);
968 bool ok_b
= KeyPrefix::Decode(&slice_b
, &prefix_b
);
971 if (!ok_a
|| !ok_b
) {
977 if (int x
= prefix_a
.Compare(prefix_b
))
980 switch (prefix_a
.type()) {
981 case KeyPrefix::GLOBAL_METADATA
: {
982 DCHECK(!slice_a
.empty());
983 DCHECK(!slice_b
.empty());
985 unsigned char type_byte_a
;
986 if (!DecodeByte(&slice_a
, &type_byte_a
)) {
991 unsigned char type_byte_b
;
992 if (!DecodeByte(&slice_b
, &type_byte_b
)) {
997 if (int x
= type_byte_a
- type_byte_b
)
999 if (type_byte_a
< kMaxSimpleGlobalMetaDataTypeByte
)
1002 // Compare<> is used (which re-decodes the prefix) rather than an
1003 // specialized CompareSuffix<> because metadata is relatively uncommon
1006 if (type_byte_a
== kDatabaseFreeListTypeByte
) {
1007 // TODO(jsbell): No need to pass only_compare_index_keys through here.
1008 return Compare
<DatabaseFreeListKey
>(a
, b
, only_compare_index_keys
, ok
);
1010 if (type_byte_a
== kDatabaseNameTypeByte
) {
1011 return Compare
<DatabaseNameKey
>(
1012 a
, b
, /*only_compare_index_keys*/ false, ok
);
1017 case KeyPrefix::DATABASE_METADATA
: {
1018 DCHECK(!slice_a
.empty());
1019 DCHECK(!slice_b
.empty());
1021 unsigned char type_byte_a
;
1022 if (!DecodeByte(&slice_a
, &type_byte_a
)) {
1027 unsigned char type_byte_b
;
1028 if (!DecodeByte(&slice_b
, &type_byte_b
)) {
1033 if (int x
= type_byte_a
- type_byte_b
)
1035 if (type_byte_a
< DatabaseMetaDataKey::MAX_SIMPLE_METADATA_TYPE
)
1038 // Compare<> is used (which re-decodes the prefix) rather than an
1039 // specialized CompareSuffix<> because metadata is relatively uncommon
1042 if (type_byte_a
== kObjectStoreMetaDataTypeByte
) {
1043 // TODO(jsbell): No need to pass only_compare_index_keys through here.
1044 return Compare
<ObjectStoreMetaDataKey
>(
1045 a
, b
, only_compare_index_keys
, ok
);
1047 if (type_byte_a
== kIndexMetaDataTypeByte
) {
1048 return Compare
<IndexMetaDataKey
>(
1049 a
, b
, /*only_compare_index_keys*/ false, ok
);
1051 if (type_byte_a
== kObjectStoreFreeListTypeByte
) {
1052 return Compare
<ObjectStoreFreeListKey
>(
1053 a
, b
, only_compare_index_keys
, ok
);
1055 if (type_byte_a
== kIndexFreeListTypeByte
) {
1056 return Compare
<IndexFreeListKey
>(
1057 a
, b
, /*only_compare_index_keys*/ false, ok
);
1059 if (type_byte_a
== kObjectStoreNamesTypeByte
) {
1060 // TODO(jsbell): No need to pass only_compare_index_keys through here.
1061 return Compare
<ObjectStoreNamesKey
>(
1062 a
, b
, only_compare_index_keys
, ok
);
1064 if (type_byte_a
== kIndexNamesKeyTypeByte
) {
1065 return Compare
<IndexNamesKey
>(
1066 a
, b
, /*only_compare_index_keys*/ false, ok
);
1071 case KeyPrefix::OBJECT_STORE_DATA
: {
1072 // Provide a stable ordering for invalid data.
1073 if (slice_a
.empty() || slice_b
.empty())
1074 return CompareSizes(slice_a
.size(), slice_b
.size());
1076 return CompareSuffix
<ObjectStoreDataKey
>(
1077 &slice_a
, &slice_b
, /*only_compare_index_keys*/ false, ok
);
1080 case KeyPrefix::EXISTS_ENTRY
: {
1081 // Provide a stable ordering for invalid data.
1082 if (slice_a
.empty() || slice_b
.empty())
1083 return CompareSizes(slice_a
.size(), slice_b
.size());
1085 return CompareSuffix
<ExistsEntryKey
>(
1086 &slice_a
, &slice_b
, /*only_compare_index_keys*/ false, ok
);
1089 case KeyPrefix::BLOB_ENTRY
: {
1090 // Provide a stable ordering for invalid data.
1091 if (slice_a
.empty() || slice_b
.empty())
1092 return CompareSizes(slice_a
.size(), slice_b
.size());
1094 return CompareSuffix
<BlobEntryKey
>(
1095 &slice_a
, &slice_b
, /*only_compare_index_keys*/ false, ok
);
1098 case KeyPrefix::INDEX_DATA
: {
1099 // Provide a stable ordering for invalid data.
1100 if (slice_a
.empty() || slice_b
.empty())
1101 return CompareSizes(slice_a
.size(), slice_b
.size());
1103 return CompareSuffix
<IndexDataKey
>(
1104 &slice_a
, &slice_b
, only_compare_index_keys
, ok
);
1107 case KeyPrefix::INVALID_TYPE
:
1118 int Compare(const StringPiece
& a
,
1119 const StringPiece
& b
,
1120 bool only_compare_index_keys
) {
1122 int result
= Compare(a
, b
, only_compare_index_keys
, &ok
);
1129 KeyPrefix::KeyPrefix()
1130 : database_id_(INVALID_TYPE
),
1131 object_store_id_(INVALID_TYPE
),
1132 index_id_(INVALID_TYPE
) {}
1134 KeyPrefix::KeyPrefix(int64 database_id
)
1135 : database_id_(database_id
), object_store_id_(0), index_id_(0) {
1136 DCHECK(KeyPrefix::IsValidDatabaseId(database_id
));
1139 KeyPrefix::KeyPrefix(int64 database_id
, int64 object_store_id
)
1140 : database_id_(database_id
),
1141 object_store_id_(object_store_id
),
1143 DCHECK(KeyPrefix::IsValidDatabaseId(database_id
));
1144 DCHECK(KeyPrefix::IsValidObjectStoreId(object_store_id
));
1147 KeyPrefix::KeyPrefix(int64 database_id
, int64 object_store_id
, int64 index_id
)
1148 : database_id_(database_id
),
1149 object_store_id_(object_store_id
),
1150 index_id_(index_id
) {
1151 DCHECK(KeyPrefix::IsValidDatabaseId(database_id
));
1152 DCHECK(KeyPrefix::IsValidObjectStoreId(object_store_id
));
1153 DCHECK(KeyPrefix::IsValidIndexId(index_id
));
1156 KeyPrefix::KeyPrefix(enum Type type
,
1158 int64 object_store_id
,
1160 : database_id_(database_id
),
1161 object_store_id_(object_store_id
),
1162 index_id_(index_id
) {
1163 DCHECK_EQ(type
, INVALID_TYPE
);
1164 DCHECK(KeyPrefix::IsValidDatabaseId(database_id
));
1165 DCHECK(KeyPrefix::IsValidObjectStoreId(object_store_id
));
1168 KeyPrefix
KeyPrefix::CreateWithSpecialIndex(int64 database_id
,
1169 int64 object_store_id
,
1171 DCHECK(KeyPrefix::IsValidDatabaseId(database_id
));
1172 DCHECK(KeyPrefix::IsValidObjectStoreId(object_store_id
));
1174 return KeyPrefix(INVALID_TYPE
, database_id
, object_store_id
, index_id
);
1177 bool KeyPrefix::IsValidDatabaseId(int64 database_id
) {
1178 return (database_id
> 0) && (database_id
< KeyPrefix::kMaxDatabaseId
);
1181 bool KeyPrefix::IsValidObjectStoreId(int64 object_store_id
) {
1182 return (object_store_id
> 0) &&
1183 (object_store_id
< KeyPrefix::kMaxObjectStoreId
);
1186 bool KeyPrefix::IsValidIndexId(int64 index_id
) {
1187 return (index_id
>= kMinimumIndexId
) && (index_id
< KeyPrefix::kMaxIndexId
);
1190 bool KeyPrefix::Decode(StringPiece
* slice
, KeyPrefix
* result
) {
1191 unsigned char first_byte
;
1192 if (!DecodeByte(slice
, &first_byte
))
1195 size_t database_id_bytes
= ((first_byte
>> 5) & 0x7) + 1;
1196 size_t object_store_id_bytes
= ((first_byte
>> 2) & 0x7) + 1;
1197 size_t index_id_bytes
= (first_byte
& 0x3) + 1;
1199 if (database_id_bytes
+ object_store_id_bytes
+ index_id_bytes
>
1204 StringPiece
tmp(slice
->begin(), database_id_bytes
);
1205 if (!DecodeInt(&tmp
, &result
->database_id_
))
1208 slice
->remove_prefix(database_id_bytes
);
1210 StringPiece
tmp(slice
->begin(), object_store_id_bytes
);
1211 if (!DecodeInt(&tmp
, &result
->object_store_id_
))
1214 slice
->remove_prefix(object_store_id_bytes
);
1216 StringPiece
tmp(slice
->begin(), index_id_bytes
);
1217 if (!DecodeInt(&tmp
, &result
->index_id_
))
1220 slice
->remove_prefix(index_id_bytes
);
1224 std::string
KeyPrefix::EncodeEmpty() {
1225 const std::string
result(4, 0);
1226 DCHECK(EncodeInternal(0, 0, 0) == std::string(4, 0));
1230 std::string
KeyPrefix::Encode() const {
1231 DCHECK(database_id_
!= kInvalidId
);
1232 DCHECK(object_store_id_
!= kInvalidId
);
1233 DCHECK(index_id_
!= kInvalidId
);
1234 return EncodeInternal(database_id_
, object_store_id_
, index_id_
);
1237 std::string
KeyPrefix::EncodeInternal(int64 database_id
,
1238 int64 object_store_id
,
1240 std::string database_id_string
;
1241 std::string object_store_id_string
;
1242 std::string index_id_string
;
1244 EncodeIntSafely(database_id
, kMaxDatabaseId
, &database_id_string
);
1245 EncodeIntSafely(object_store_id
, kMaxObjectStoreId
, &object_store_id_string
);
1246 EncodeIntSafely(index_id
, kMaxIndexId
, &index_id_string
);
1248 DCHECK(database_id_string
.size() <= kMaxDatabaseIdSizeBytes
);
1249 DCHECK(object_store_id_string
.size() <= kMaxObjectStoreIdSizeBytes
);
1250 DCHECK(index_id_string
.size() <= kMaxIndexIdSizeBytes
);
1252 unsigned char first_byte
=
1253 (database_id_string
.size() - 1) << (kMaxObjectStoreIdSizeBits
+
1254 kMaxIndexIdSizeBits
) |
1255 (object_store_id_string
.size() - 1) << kMaxIndexIdSizeBits
|
1256 (index_id_string
.size() - 1);
1257 COMPILE_ASSERT(kMaxDatabaseIdSizeBits
+ kMaxObjectStoreIdSizeBits
+
1258 kMaxIndexIdSizeBits
==
1259 sizeof(first_byte
) * 8,
1262 ret
.reserve(kDefaultInlineBufferSize
);
1263 ret
.push_back(first_byte
);
1264 ret
.append(database_id_string
);
1265 ret
.append(object_store_id_string
);
1266 ret
.append(index_id_string
);
1268 DCHECK_LE(ret
.size(), kDefaultInlineBufferSize
);
1272 int KeyPrefix::Compare(const KeyPrefix
& other
) const {
1273 DCHECK(database_id_
!= kInvalidId
);
1274 DCHECK(object_store_id_
!= kInvalidId
);
1275 DCHECK(index_id_
!= kInvalidId
);
1277 if (database_id_
!= other
.database_id_
)
1278 return CompareInts(database_id_
, other
.database_id_
);
1279 if (object_store_id_
!= other
.object_store_id_
)
1280 return CompareInts(object_store_id_
, other
.object_store_id_
);
1281 if (index_id_
!= other
.index_id_
)
1282 return CompareInts(index_id_
, other
.index_id_
);
1286 KeyPrefix::Type
KeyPrefix::type() const {
1287 DCHECK(database_id_
!= kInvalidId
);
1288 DCHECK(object_store_id_
!= kInvalidId
);
1289 DCHECK(index_id_
!= kInvalidId
);
1292 return GLOBAL_METADATA
;
1293 if (!object_store_id_
)
1294 return DATABASE_METADATA
;
1295 if (index_id_
== kObjectStoreDataIndexId
)
1296 return OBJECT_STORE_DATA
;
1297 if (index_id_
== kExistsEntryIndexId
)
1298 return EXISTS_ENTRY
;
1299 if (index_id_
== kBlobEntryIndexId
)
1301 if (index_id_
>= kMinimumIndexId
)
1305 return INVALID_TYPE
;
1308 std::string
SchemaVersionKey::Encode() {
1309 std::string ret
= KeyPrefix::EncodeEmpty();
1310 ret
.push_back(kSchemaVersionTypeByte
);
1314 std::string
MaxDatabaseIdKey::Encode() {
1315 std::string ret
= KeyPrefix::EncodeEmpty();
1316 ret
.push_back(kMaxDatabaseIdTypeByte
);
1320 std::string
DataVersionKey::Encode() {
1321 std::string ret
= KeyPrefix::EncodeEmpty();
1322 ret
.push_back(kDataVersionTypeByte
);
1326 std::string
BlobJournalKey::Encode() {
1327 std::string ret
= KeyPrefix::EncodeEmpty();
1328 ret
.push_back(kBlobJournalTypeByte
);
1332 std::string
LiveBlobJournalKey::Encode() {
1333 std::string ret
= KeyPrefix::EncodeEmpty();
1334 ret
.push_back(kLiveBlobJournalTypeByte
);
1338 DatabaseFreeListKey::DatabaseFreeListKey() : database_id_(-1) {}
1340 bool DatabaseFreeListKey::Decode(StringPiece
* slice
,
1341 DatabaseFreeListKey
* result
) {
1343 if (!KeyPrefix::Decode(slice
, &prefix
))
1345 DCHECK(!prefix
.database_id_
);
1346 DCHECK(!prefix
.object_store_id_
);
1347 DCHECK(!prefix
.index_id_
);
1348 unsigned char type_byte
= 0;
1349 if (!DecodeByte(slice
, &type_byte
))
1351 DCHECK_EQ(type_byte
, kDatabaseFreeListTypeByte
);
1352 if (!DecodeVarInt(slice
, &result
->database_id_
))
1357 std::string
DatabaseFreeListKey::Encode(int64 database_id
) {
1358 std::string ret
= KeyPrefix::EncodeEmpty();
1359 ret
.push_back(kDatabaseFreeListTypeByte
);
1360 EncodeVarInt(database_id
, &ret
);
1364 std::string
DatabaseFreeListKey::EncodeMaxKey() {
1365 return Encode(std::numeric_limits
<int64
>::max());
1368 int64
DatabaseFreeListKey::DatabaseId() const {
1369 DCHECK_GE(database_id_
, 0);
1370 return database_id_
;
1373 int DatabaseFreeListKey::Compare(const DatabaseFreeListKey
& other
) const {
1374 DCHECK_GE(database_id_
, 0);
1375 return CompareInts(database_id_
, other
.database_id_
);
1378 bool DatabaseNameKey::Decode(StringPiece
* slice
, DatabaseNameKey
* result
) {
1380 if (!KeyPrefix::Decode(slice
, &prefix
))
1382 DCHECK(!prefix
.database_id_
);
1383 DCHECK(!prefix
.object_store_id_
);
1384 DCHECK(!prefix
.index_id_
);
1385 unsigned char type_byte
= 0;
1386 if (!DecodeByte(slice
, &type_byte
))
1388 DCHECK_EQ(type_byte
, kDatabaseNameTypeByte
);
1389 if (!DecodeStringWithLength(slice
, &result
->origin_
))
1391 if (!DecodeStringWithLength(slice
, &result
->database_name_
))
1396 std::string
DatabaseNameKey::Encode(const std::string
& origin_identifier
,
1397 const base::string16
& database_name
) {
1398 std::string ret
= KeyPrefix::EncodeEmpty();
1399 ret
.push_back(kDatabaseNameTypeByte
);
1400 EncodeStringWithLength(base::ASCIIToUTF16(origin_identifier
), &ret
);
1401 EncodeStringWithLength(database_name
, &ret
);
1405 std::string
DatabaseNameKey::EncodeMinKeyForOrigin(
1406 const std::string
& origin_identifier
) {
1407 return Encode(origin_identifier
, base::string16());
1410 std::string
DatabaseNameKey::EncodeStopKeyForOrigin(
1411 const std::string
& origin_identifier
) {
1412 // just after origin in collation order
1413 return EncodeMinKeyForOrigin(origin_identifier
+ '\x01');
1416 int DatabaseNameKey::Compare(const DatabaseNameKey
& other
) {
1417 if (int x
= origin_
.compare(other
.origin_
))
1419 return database_name_
.compare(other
.database_name_
);
1422 bool DatabaseMetaDataKey::IsValidBlobKey(int64 blob_key
) {
1423 return blob_key
>= kBlobKeyGeneratorInitialNumber
;
1426 const int64
DatabaseMetaDataKey::kAllBlobsKey
= 1;
1427 const int64
DatabaseMetaDataKey::kBlobKeyGeneratorInitialNumber
= 2;
1428 const int64
DatabaseMetaDataKey::kInvalidBlobKey
= -1;
1430 std::string
DatabaseMetaDataKey::Encode(int64 database_id
,
1431 MetaDataType meta_data_type
) {
1432 KeyPrefix
prefix(database_id
);
1433 std::string ret
= prefix
.Encode();
1434 ret
.push_back(meta_data_type
);
1438 ObjectStoreMetaDataKey::ObjectStoreMetaDataKey()
1439 : object_store_id_(-1), meta_data_type_(0xFF) {}
1441 bool ObjectStoreMetaDataKey::Decode(StringPiece
* slice
,
1442 ObjectStoreMetaDataKey
* result
) {
1444 if (!KeyPrefix::Decode(slice
, &prefix
))
1446 DCHECK(prefix
.database_id_
);
1447 DCHECK(!prefix
.object_store_id_
);
1448 DCHECK(!prefix
.index_id_
);
1449 unsigned char type_byte
= 0;
1450 if (!DecodeByte(slice
, &type_byte
))
1452 DCHECK_EQ(type_byte
, kObjectStoreMetaDataTypeByte
);
1453 if (!DecodeVarInt(slice
, &result
->object_store_id_
))
1455 DCHECK(result
->object_store_id_
);
1456 if (!DecodeByte(slice
, &result
->meta_data_type_
))
1461 std::string
ObjectStoreMetaDataKey::Encode(int64 database_id
,
1462 int64 object_store_id
,
1463 unsigned char meta_data_type
) {
1464 KeyPrefix
prefix(database_id
);
1465 std::string ret
= prefix
.Encode();
1466 ret
.push_back(kObjectStoreMetaDataTypeByte
);
1467 EncodeVarInt(object_store_id
, &ret
);
1468 ret
.push_back(meta_data_type
);
1472 std::string
ObjectStoreMetaDataKey::EncodeMaxKey(int64 database_id
) {
1473 return Encode(database_id
,
1474 std::numeric_limits
<int64
>::max(),
1475 kObjectMetaDataTypeMaximum
);
1478 std::string
ObjectStoreMetaDataKey::EncodeMaxKey(int64 database_id
,
1479 int64 object_store_id
) {
1480 return Encode(database_id
, object_store_id
, kObjectMetaDataTypeMaximum
);
1483 int64
ObjectStoreMetaDataKey::ObjectStoreId() const {
1484 DCHECK_GE(object_store_id_
, 0);
1485 return object_store_id_
;
1487 unsigned char ObjectStoreMetaDataKey::MetaDataType() const {
1488 return meta_data_type_
;
1491 int ObjectStoreMetaDataKey::Compare(const ObjectStoreMetaDataKey
& other
) {
1492 DCHECK_GE(object_store_id_
, 0);
1493 if (int x
= CompareInts(object_store_id_
, other
.object_store_id_
))
1495 return meta_data_type_
- other
.meta_data_type_
;
1498 IndexMetaDataKey::IndexMetaDataKey()
1499 : object_store_id_(-1), index_id_(-1), meta_data_type_(0) {}
1501 bool IndexMetaDataKey::Decode(StringPiece
* slice
, IndexMetaDataKey
* result
) {
1503 if (!KeyPrefix::Decode(slice
, &prefix
))
1505 DCHECK(prefix
.database_id_
);
1506 DCHECK(!prefix
.object_store_id_
);
1507 DCHECK(!prefix
.index_id_
);
1508 unsigned char type_byte
= 0;
1509 if (!DecodeByte(slice
, &type_byte
))
1511 DCHECK_EQ(type_byte
, kIndexMetaDataTypeByte
);
1512 if (!DecodeVarInt(slice
, &result
->object_store_id_
))
1514 if (!DecodeVarInt(slice
, &result
->index_id_
))
1516 if (!DecodeByte(slice
, &result
->meta_data_type_
))
1521 std::string
IndexMetaDataKey::Encode(int64 database_id
,
1522 int64 object_store_id
,
1524 unsigned char meta_data_type
) {
1525 KeyPrefix
prefix(database_id
);
1526 std::string ret
= prefix
.Encode();
1527 ret
.push_back(kIndexMetaDataTypeByte
);
1528 EncodeVarInt(object_store_id
, &ret
);
1529 EncodeVarInt(index_id
, &ret
);
1530 EncodeByte(meta_data_type
, &ret
);
1534 std::string
IndexMetaDataKey::EncodeMaxKey(int64 database_id
,
1535 int64 object_store_id
) {
1536 return Encode(database_id
,
1538 std::numeric_limits
<int64
>::max(),
1539 kIndexMetaDataTypeMaximum
);
1542 std::string
IndexMetaDataKey::EncodeMaxKey(int64 database_id
,
1543 int64 object_store_id
,
1546 database_id
, object_store_id
, index_id
, kIndexMetaDataTypeMaximum
);
1549 int IndexMetaDataKey::Compare(const IndexMetaDataKey
& other
) {
1550 DCHECK_GE(object_store_id_
, 0);
1551 DCHECK_GE(index_id_
, 0);
1553 if (int x
= CompareInts(object_store_id_
, other
.object_store_id_
))
1555 if (int x
= CompareInts(index_id_
, other
.index_id_
))
1557 return meta_data_type_
- other
.meta_data_type_
;
1560 int64
IndexMetaDataKey::IndexId() const {
1561 DCHECK_GE(index_id_
, 0);
1565 ObjectStoreFreeListKey::ObjectStoreFreeListKey() : object_store_id_(-1) {}
1567 bool ObjectStoreFreeListKey::Decode(StringPiece
* slice
,
1568 ObjectStoreFreeListKey
* result
) {
1570 if (!KeyPrefix::Decode(slice
, &prefix
))
1572 DCHECK(prefix
.database_id_
);
1573 DCHECK(!prefix
.object_store_id_
);
1574 DCHECK(!prefix
.index_id_
);
1575 unsigned char type_byte
= 0;
1576 if (!DecodeByte(slice
, &type_byte
))
1578 DCHECK_EQ(type_byte
, kObjectStoreFreeListTypeByte
);
1579 if (!DecodeVarInt(slice
, &result
->object_store_id_
))
1584 std::string
ObjectStoreFreeListKey::Encode(int64 database_id
,
1585 int64 object_store_id
) {
1586 KeyPrefix
prefix(database_id
);
1587 std::string ret
= prefix
.Encode();
1588 ret
.push_back(kObjectStoreFreeListTypeByte
);
1589 EncodeVarInt(object_store_id
, &ret
);
1593 std::string
ObjectStoreFreeListKey::EncodeMaxKey(int64 database_id
) {
1594 return Encode(database_id
, std::numeric_limits
<int64
>::max());
1597 int64
ObjectStoreFreeListKey::ObjectStoreId() const {
1598 DCHECK_GE(object_store_id_
, 0);
1599 return object_store_id_
;
1602 int ObjectStoreFreeListKey::Compare(const ObjectStoreFreeListKey
& other
) {
1603 // TODO(jsbell): It may seem strange that we're not comparing database id's,
1604 // but that comparison will have been made earlier.
1605 // We should probably make this more clear, though...
1606 DCHECK_GE(object_store_id_
, 0);
1607 return CompareInts(object_store_id_
, other
.object_store_id_
);
1610 IndexFreeListKey::IndexFreeListKey() : object_store_id_(-1), index_id_(-1) {}
1612 bool IndexFreeListKey::Decode(StringPiece
* slice
, IndexFreeListKey
* result
) {
1614 if (!KeyPrefix::Decode(slice
, &prefix
))
1616 DCHECK(prefix
.database_id_
);
1617 DCHECK(!prefix
.object_store_id_
);
1618 DCHECK(!prefix
.index_id_
);
1619 unsigned char type_byte
= 0;
1620 if (!DecodeByte(slice
, &type_byte
))
1622 DCHECK_EQ(type_byte
, kIndexFreeListTypeByte
);
1623 if (!DecodeVarInt(slice
, &result
->object_store_id_
))
1625 if (!DecodeVarInt(slice
, &result
->index_id_
))
1630 std::string
IndexFreeListKey::Encode(int64 database_id
,
1631 int64 object_store_id
,
1633 KeyPrefix
prefix(database_id
);
1634 std::string ret
= prefix
.Encode();
1635 ret
.push_back(kIndexFreeListTypeByte
);
1636 EncodeVarInt(object_store_id
, &ret
);
1637 EncodeVarInt(index_id
, &ret
);
1641 std::string
IndexFreeListKey::EncodeMaxKey(int64 database_id
,
1642 int64 object_store_id
) {
1644 database_id
, object_store_id
, std::numeric_limits
<int64
>::max());
1647 int IndexFreeListKey::Compare(const IndexFreeListKey
& other
) {
1648 DCHECK_GE(object_store_id_
, 0);
1649 DCHECK_GE(index_id_
, 0);
1650 if (int x
= CompareInts(object_store_id_
, other
.object_store_id_
))
1652 return CompareInts(index_id_
, other
.index_id_
);
1655 int64
IndexFreeListKey::ObjectStoreId() const {
1656 DCHECK_GE(object_store_id_
, 0);
1657 return object_store_id_
;
1660 int64
IndexFreeListKey::IndexId() const {
1661 DCHECK_GE(index_id_
, 0);
1665 // TODO(jsbell): We never use this to look up object store ids,
1666 // because a mapping is kept in the IndexedDBDatabase. Can the
1667 // mapping become unreliable? Can we remove this?
1668 bool ObjectStoreNamesKey::Decode(StringPiece
* slice
,
1669 ObjectStoreNamesKey
* result
) {
1671 if (!KeyPrefix::Decode(slice
, &prefix
))
1673 DCHECK(prefix
.database_id_
);
1674 DCHECK(!prefix
.object_store_id_
);
1675 DCHECK(!prefix
.index_id_
);
1676 unsigned char type_byte
= 0;
1677 if (!DecodeByte(slice
, &type_byte
))
1679 DCHECK_EQ(type_byte
, kObjectStoreNamesTypeByte
);
1680 if (!DecodeStringWithLength(slice
, &result
->object_store_name_
))
1685 std::string
ObjectStoreNamesKey::Encode(
1687 const base::string16
& object_store_name
) {
1688 KeyPrefix
prefix(database_id
);
1689 std::string ret
= prefix
.Encode();
1690 ret
.push_back(kObjectStoreNamesTypeByte
);
1691 EncodeStringWithLength(object_store_name
, &ret
);
1695 int ObjectStoreNamesKey::Compare(const ObjectStoreNamesKey
& other
) {
1696 return object_store_name_
.compare(other
.object_store_name_
);
1699 IndexNamesKey::IndexNamesKey() : object_store_id_(-1) {}
1701 // TODO(jsbell): We never use this to look up index ids, because a mapping
1702 // is kept at a higher level.
1703 bool IndexNamesKey::Decode(StringPiece
* slice
, IndexNamesKey
* result
) {
1705 if (!KeyPrefix::Decode(slice
, &prefix
))
1707 DCHECK(prefix
.database_id_
);
1708 DCHECK(!prefix
.object_store_id_
);
1709 DCHECK(!prefix
.index_id_
);
1710 unsigned char type_byte
= 0;
1711 if (!DecodeByte(slice
, &type_byte
))
1713 DCHECK_EQ(type_byte
, kIndexNamesKeyTypeByte
);
1714 if (!DecodeVarInt(slice
, &result
->object_store_id_
))
1716 if (!DecodeStringWithLength(slice
, &result
->index_name_
))
1721 std::string
IndexNamesKey::Encode(int64 database_id
,
1722 int64 object_store_id
,
1723 const base::string16
& index_name
) {
1724 KeyPrefix
prefix(database_id
);
1725 std::string ret
= prefix
.Encode();
1726 ret
.push_back(kIndexNamesKeyTypeByte
);
1727 EncodeVarInt(object_store_id
, &ret
);
1728 EncodeStringWithLength(index_name
, &ret
);
1732 int IndexNamesKey::Compare(const IndexNamesKey
& other
) {
1733 DCHECK_GE(object_store_id_
, 0);
1734 if (int x
= CompareInts(object_store_id_
, other
.object_store_id_
))
1736 return index_name_
.compare(other
.index_name_
);
1739 ObjectStoreDataKey::ObjectStoreDataKey() {}
1740 ObjectStoreDataKey::~ObjectStoreDataKey() {}
1742 bool ObjectStoreDataKey::Decode(StringPiece
* slice
,
1743 ObjectStoreDataKey
* result
) {
1745 if (!KeyPrefix::Decode(slice
, &prefix
))
1747 DCHECK(prefix
.database_id_
);
1748 DCHECK(prefix
.object_store_id_
);
1749 DCHECK_EQ(prefix
.index_id_
, kSpecialIndexNumber
);
1750 if (!ExtractEncodedIDBKey(slice
, &result
->encoded_user_key_
))
1755 std::string
ObjectStoreDataKey::Encode(int64 database_id
,
1756 int64 object_store_id
,
1757 const std::string encoded_user_key
) {
1758 KeyPrefix
prefix(KeyPrefix::CreateWithSpecialIndex(
1759 database_id
, object_store_id
, kSpecialIndexNumber
));
1760 std::string ret
= prefix
.Encode();
1761 ret
.append(encoded_user_key
);
1766 std::string
ObjectStoreDataKey::Encode(int64 database_id
,
1767 int64 object_store_id
,
1768 const IndexedDBKey
& user_key
) {
1769 std::string encoded_key
;
1770 EncodeIDBKey(user_key
, &encoded_key
);
1771 return Encode(database_id
, object_store_id
, encoded_key
);
1774 scoped_ptr
<IndexedDBKey
> ObjectStoreDataKey::user_key() const {
1775 scoped_ptr
<IndexedDBKey
> key
;
1776 StringPiece
slice(encoded_user_key_
);
1777 if (!DecodeIDBKey(&slice
, &key
)) {
1778 // TODO(jsbell): Return error.
1783 const int64
ObjectStoreDataKey::kSpecialIndexNumber
= kObjectStoreDataIndexId
;
1785 ExistsEntryKey::ExistsEntryKey() {}
1786 ExistsEntryKey::~ExistsEntryKey() {}
1788 bool ExistsEntryKey::Decode(StringPiece
* slice
, ExistsEntryKey
* result
) {
1790 if (!KeyPrefix::Decode(slice
, &prefix
))
1792 DCHECK(prefix
.database_id_
);
1793 DCHECK(prefix
.object_store_id_
);
1794 DCHECK_EQ(prefix
.index_id_
, kSpecialIndexNumber
);
1795 if (!ExtractEncodedIDBKey(slice
, &result
->encoded_user_key_
))
1800 std::string
ExistsEntryKey::Encode(int64 database_id
,
1801 int64 object_store_id
,
1802 const std::string
& encoded_key
) {
1803 KeyPrefix
prefix(KeyPrefix::CreateWithSpecialIndex(
1804 database_id
, object_store_id
, kSpecialIndexNumber
));
1805 std::string ret
= prefix
.Encode();
1806 ret
.append(encoded_key
);
1810 std::string
ExistsEntryKey::Encode(int64 database_id
,
1811 int64 object_store_id
,
1812 const IndexedDBKey
& user_key
) {
1813 std::string encoded_key
;
1814 EncodeIDBKey(user_key
, &encoded_key
);
1815 return Encode(database_id
, object_store_id
, encoded_key
);
1818 scoped_ptr
<IndexedDBKey
> ExistsEntryKey::user_key() const {
1819 scoped_ptr
<IndexedDBKey
> key
;
1820 StringPiece
slice(encoded_user_key_
);
1821 if (!DecodeIDBKey(&slice
, &key
)) {
1822 // TODO(jsbell): Return error.
1827 const int64
ExistsEntryKey::kSpecialIndexNumber
= kExistsEntryIndexId
;
1829 bool BlobEntryKey::Decode(StringPiece
* slice
, BlobEntryKey
* result
) {
1831 if (!KeyPrefix::Decode(slice
, &prefix
))
1833 DCHECK(prefix
.database_id_
);
1834 DCHECK(prefix
.object_store_id_
);
1835 DCHECK_EQ(prefix
.index_id_
, kSpecialIndexNumber
);
1837 if (!ExtractEncodedIDBKey(slice
, &result
->encoded_user_key_
))
1839 result
->database_id_
= prefix
.database_id_
;
1840 result
->object_store_id_
= prefix
.object_store_id_
;
1845 bool BlobEntryKey::FromObjectStoreDataKey(StringPiece
* slice
,
1846 BlobEntryKey
* result
) {
1848 if (!KeyPrefix::Decode(slice
, &prefix
))
1850 DCHECK(prefix
.database_id_
);
1851 DCHECK(prefix
.object_store_id_
);
1852 DCHECK_EQ(prefix
.index_id_
, ObjectStoreDataKey::kSpecialIndexNumber
);
1854 if (!ExtractEncodedIDBKey(slice
, &result
->encoded_user_key_
))
1856 result
->database_id_
= prefix
.database_id_
;
1857 result
->object_store_id_
= prefix
.object_store_id_
;
1861 std::string
BlobEntryKey::ReencodeToObjectStoreDataKey(StringPiece
* slice
) {
1862 // TODO(ericu): We could be more efficient here, since the suffix is the same.
1864 if (!Decode(slice
, &key
))
1865 return std::string();
1867 return ObjectStoreDataKey::Encode(
1868 key
.database_id_
, key
.object_store_id_
, key
.encoded_user_key_
);
1871 std::string
BlobEntryKey::EncodeMinKeyForObjectStore(int64 database_id
,
1872 int64 object_store_id
) {
1873 // Our implied encoded_user_key_ here is empty, the lowest possible key.
1874 return Encode(database_id
, object_store_id
, std::string());
1877 std::string
BlobEntryKey::EncodeStopKeyForObjectStore(int64 database_id
,
1878 int64 object_store_id
) {
1879 DCHECK(KeyPrefix::ValidIds(database_id
, object_store_id
));
1880 KeyPrefix
prefix(KeyPrefix::CreateWithSpecialIndex(
1881 database_id
, object_store_id
, kSpecialIndexNumber
+ 1));
1882 return prefix
.Encode();
1885 std::string
BlobEntryKey::Encode() const {
1886 DCHECK(!encoded_user_key_
.empty());
1887 return Encode(database_id_
, object_store_id_
, encoded_user_key_
);
1890 std::string
BlobEntryKey::Encode(int64 database_id
,
1891 int64 object_store_id
,
1892 const IndexedDBKey
& user_key
) {
1893 std::string encoded_key
;
1894 EncodeIDBKey(user_key
, &encoded_key
);
1895 return Encode(database_id
, object_store_id
, encoded_key
);
1898 std::string
BlobEntryKey::Encode(int64 database_id
,
1899 int64 object_store_id
,
1900 const std::string
& encoded_user_key
) {
1901 DCHECK(KeyPrefix::ValidIds(database_id
, object_store_id
));
1902 KeyPrefix
prefix(KeyPrefix::CreateWithSpecialIndex(
1903 database_id
, object_store_id
, kSpecialIndexNumber
));
1904 return prefix
.Encode() + encoded_user_key
;
1907 const int64
BlobEntryKey::kSpecialIndexNumber
= kBlobEntryIndexId
;
1909 IndexDataKey::IndexDataKey()
1911 object_store_id_(-1),
1913 sequence_number_(-1) {}
1915 IndexDataKey::~IndexDataKey() {}
1917 bool IndexDataKey::Decode(StringPiece
* slice
, IndexDataKey
* result
) {
1919 if (!KeyPrefix::Decode(slice
, &prefix
))
1921 DCHECK(prefix
.database_id_
);
1922 DCHECK(prefix
.object_store_id_
);
1923 DCHECK_GE(prefix
.index_id_
, kMinimumIndexId
);
1924 result
->database_id_
= prefix
.database_id_
;
1925 result
->object_store_id_
= prefix
.object_store_id_
;
1926 result
->index_id_
= prefix
.index_id_
;
1927 result
->sequence_number_
= -1;
1928 result
->encoded_primary_key_
= MinIDBKey();
1930 if (!ExtractEncodedIDBKey(slice
, &result
->encoded_user_key_
))
1933 // [optional] sequence number
1936 if (!DecodeVarInt(slice
, &result
->sequence_number_
))
1939 // [optional] primary key
1942 if (!ExtractEncodedIDBKey(slice
, &result
->encoded_primary_key_
))
1947 std::string
IndexDataKey::Encode(int64 database_id
,
1948 int64 object_store_id
,
1950 const std::string
& encoded_user_key
,
1951 const std::string
& encoded_primary_key
,
1952 int64 sequence_number
) {
1953 KeyPrefix
prefix(database_id
, object_store_id
, index_id
);
1954 std::string ret
= prefix
.Encode();
1955 ret
.append(encoded_user_key
);
1956 EncodeVarInt(sequence_number
, &ret
);
1957 ret
.append(encoded_primary_key
);
1961 std::string
IndexDataKey::Encode(int64 database_id
,
1962 int64 object_store_id
,
1964 const IndexedDBKey
& user_key
) {
1965 std::string encoded_key
;
1966 EncodeIDBKey(user_key
, &encoded_key
);
1968 database_id
, object_store_id
, index_id
, encoded_key
, MinIDBKey(), 0);
1971 std::string
IndexDataKey::Encode(int64 database_id
,
1972 int64 object_store_id
,
1974 const IndexedDBKey
& user_key
,
1975 const IndexedDBKey
& user_primary_key
) {
1976 std::string encoded_key
;
1977 EncodeIDBKey(user_key
, &encoded_key
);
1978 std::string encoded_primary_key
;
1979 EncodeIDBKey(user_primary_key
, &encoded_primary_key
);
1980 return Encode(database_id
,
1984 encoded_primary_key
,
1988 std::string
IndexDataKey::EncodeMinKey(int64 database_id
,
1989 int64 object_store_id
,
1992 database_id
, object_store_id
, index_id
, MinIDBKey(), MinIDBKey(), 0);
1995 std::string
IndexDataKey::EncodeMaxKey(int64 database_id
,
1996 int64 object_store_id
,
1998 return Encode(database_id
,
2003 std::numeric_limits
<int64
>::max());
2006 int64
IndexDataKey::DatabaseId() const {
2007 DCHECK_GE(database_id_
, 0);
2008 return database_id_
;
2011 int64
IndexDataKey::ObjectStoreId() const {
2012 DCHECK_GE(object_store_id_
, 0);
2013 return object_store_id_
;
2016 int64
IndexDataKey::IndexId() const {
2017 DCHECK_GE(index_id_
, 0);
2021 scoped_ptr
<IndexedDBKey
> IndexDataKey::user_key() const {
2022 scoped_ptr
<IndexedDBKey
> key
;
2023 StringPiece
slice(encoded_user_key_
);
2024 if (!DecodeIDBKey(&slice
, &key
)) {
2025 // TODO(jsbell): Return error.
2030 scoped_ptr
<IndexedDBKey
> IndexDataKey::primary_key() const {
2031 scoped_ptr
<IndexedDBKey
> key
;
2032 StringPiece
slice(encoded_primary_key_
);
2033 if (!DecodeIDBKey(&slice
, &key
)) {
2034 // TODO(jsbell): Return error.
2039 } // namespace content