Remove PlatformFile from profile_browsertest
[chromium-blink-merge.git] / content / browser / indexed_db / indexed_db_leveldb_coding.cc
blob44556833f69543eb6ee523724a9c01e9dc8e4f44
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"
7 #include <iterator>
8 #include <limits>
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.
40 // Global metadata
41 // ---------------
42 // The prefix is <0, 0, 0>, followed by a metadata type byte:
44 // <0, 0, 0, 0> => backing store schema version [SchemaVersionKey]
45 // <0, 0, 0, 1> => maximum allocated database [MaxDatabaseIdKey]
46 // <0, 0, 0, 2> => SerializedScriptValue version [DataVersionKey]
47 // <0, 0, 0, 3>
48 // => Blob journal
49 // The format of the journal is: {database_id, blobKey}*.
50 // If the blobKey is kAllBlobsKey, the whole database should be deleted.
51 // [BlobJournalKey]
52 // <0, 0, 0, 4> => Live blob journal; same format. [LiveBlobJournalKey]
53 // <0, 0, 0, 100, database id>
54 // => Existence implies the database id is in the free list
55 // [DatabaseFreeListKey]
56 // <0, 0, 0, 201, origin, database name> => Database id [DatabaseNameKey]
59 // Database metadata: [DatabaseMetaDataKey]
60 // ----------------------------------------
61 // The prefix is <database id, 0, 0> followed by a metadata type byte:
63 // <database id, 0, 0, 0> => origin name
64 // <database id, 0, 0, 1> => database name
65 // <database id, 0, 0, 2> => IDB string version data (obsolete)
66 // <database id, 0, 0, 3> => maximum allocated object store id
67 // <database id, 0, 0, 4> => IDB integer version (var int)
68 // <database id, 0, 0, 5> => blob key generator current number
71 // Object store metadata: [ObjectStoreMetaDataKey]
72 // -----------------------------------------------
73 // The prefix is <database id, 0, 0>, followed by a type byte (50), then the
74 // object store id (var int), then a metadata type byte.
76 // <database id, 0, 0, 50, object store id, 0> => object store name
77 // <database id, 0, 0, 50, object store id, 1> => key path
78 // <database id, 0, 0, 50, object store id, 2> => auto increment flag
79 // <database id, 0, 0, 50, object store id, 3> => is evictable
80 // <database id, 0, 0, 50, object store id, 4> => last "version" number
81 // <database id, 0, 0, 50, object store id, 5> => maximum allocated index id
82 // <database id, 0, 0, 50, object store id, 6> => has key path flag (obsolete)
83 // <database id, 0, 0, 50, object store id, 7> => key generator current number
85 // The key path was originally just a string (#1) or null (identified by flag,
86 // #6). To support null, string, or array the coding is now identified by the
87 // leading bytes in #1 - see EncodeIDBKeyPath.
89 // The "version" field is used to weed out stale index data. Whenever new
90 // object store data is inserted, it gets a new "version" number, and new
91 // index data is written with this number. When the index is used for
92 // look-ups, entries are validated against the "exists" entries, and records
93 // with old "version" numbers are deleted when they are encountered in
94 // GetPrimaryKeyViaIndex, IndexCursorImpl::LoadCurrentRow and
95 // IndexKeyCursorImpl::LoadCurrentRow.
98 // Index metadata: [IndexMetaDataKey]
99 // ----------------------------------
100 // The prefix is <database id, 0, 0>, followed by a type byte (100), then the
101 // object store id (var int), then the index id (var int), then a metadata
102 // type byte.
104 // <database id, 0, 0, 100, object store id, index id, 0> => index name
105 // <database id, 0, 0, 100, object store id, index id, 1> => unique flag
106 // <database id, 0, 0, 100, object store id, index id, 2> => key path
107 // <database id, 0, 0, 100, object store id, index id, 3> => multi-entry flag
110 // Other object store and index metadata
111 // -------------------------------------
112 // The prefix is <database id, 0, 0> followed by a type byte. The object
113 // store and index id are variable length integers, the names are variable
114 // length strings.
116 // <database id, 0, 0, 150, object store id>
117 // => existence implies the object store id is in the free list
118 // [ObjectStoreFreeListKey]
119 // <database id, 0, 0, 151, object store id, index id>
120 // => existence implies the index id is in the free list [IndexFreeListKey]
121 // <database id, 0, 0, 200, object store name>
122 // => object store id [ObjectStoreNamesKey]
123 // <database id, 0, 0, 201, object store id, index name>
124 // => index id [IndexNamesKey]
127 // Object store data: [ObjectStoreDataKey]
128 // ---------------------------------------
129 // The prefix is followed by a type byte and the encoded IDB primary key. The
130 // data has a "version" prefix followed by the serialized script value.
132 // <database id, object store id, 1, user key>
133 // => "version", serialized script value
136 // "Exists" entry: [ExistsEntryKey]
137 // --------------------------------
138 // The prefix is followed by a type byte and the encoded IDB primary key.
140 // <database id, object store id, 2, user key> => "version"
143 // Blob entry table: [BlobEntryKey]
144 // --------------------------------
146 // The prefix is followed by a type byte and the encoded IDB primary key.
148 // <database id, object store id, 3, user key> => array of IndexedDBBlobInfo
151 // Index data
152 // ----------
153 // The prefix is followed by a type byte, the encoded IDB index key, a
154 // "sequence" number (obsolete; var int), and the encoded IDB primary key.
156 // <database id, object store id, index id, index key, sequence number,
157 // primary key> => "version", primary key [IndexDataKey]
159 // The sequence number is obsolete; it was used to allow two entries with the
160 // same user (index) key in non-unique indexes prior to the inclusion of the
161 // primary key in the data.
163 using base::StringPiece;
164 using blink::WebIDBKeyType;
165 using blink::WebIDBKeyTypeArray;
166 using blink::WebIDBKeyTypeBinary;
167 using blink::WebIDBKeyTypeDate;
168 using blink::WebIDBKeyTypeInvalid;
169 using blink::WebIDBKeyTypeMin;
170 using blink::WebIDBKeyTypeNull;
171 using blink::WebIDBKeyTypeNumber;
172 using blink::WebIDBKeyTypeString;
173 using blink::WebIDBKeyPathType;
174 using blink::WebIDBKeyPathTypeArray;
175 using blink::WebIDBKeyPathTypeNull;
176 using blink::WebIDBKeyPathTypeString;
178 namespace content {
180 // As most of the IndexedDBKeys and encoded values are short, we
181 // initialize some std::vectors with a default inline buffer size to reduce
182 // the memory re-allocations when the std::vectors are appended.
183 static const size_t kDefaultInlineBufferSize = 32;
185 static const unsigned char kIndexedDBKeyNullTypeByte = 0;
186 static const unsigned char kIndexedDBKeyStringTypeByte = 1;
187 static const unsigned char kIndexedDBKeyDateTypeByte = 2;
188 static const unsigned char kIndexedDBKeyNumberTypeByte = 3;
189 static const unsigned char kIndexedDBKeyArrayTypeByte = 4;
190 static const unsigned char kIndexedDBKeyMinKeyTypeByte = 5;
191 static const unsigned char kIndexedDBKeyBinaryTypeByte = 6;
193 static const unsigned char kIndexedDBKeyPathTypeCodedByte1 = 0;
194 static const unsigned char kIndexedDBKeyPathTypeCodedByte2 = 0;
196 static const unsigned char kObjectStoreDataIndexId = 1;
197 static const unsigned char kExistsEntryIndexId = 2;
198 static const unsigned char kBlobEntryIndexId = 3;
200 static const unsigned char kSchemaVersionTypeByte = 0;
201 static const unsigned char kMaxDatabaseIdTypeByte = 1;
202 static const unsigned char kDataVersionTypeByte = 2;
203 static const unsigned char kBlobJournalTypeByte = 3;
204 static const unsigned char kLiveBlobJournalTypeByte = 4;
205 static const unsigned char kMaxSimpleGlobalMetaDataTypeByte =
206 5; // Insert before this and increment.
207 static const unsigned char kDatabaseFreeListTypeByte = 100;
208 static const unsigned char kDatabaseNameTypeByte = 201;
210 static const unsigned char kObjectStoreMetaDataTypeByte = 50;
211 static const unsigned char kIndexMetaDataTypeByte = 100;
212 static const unsigned char kObjectStoreFreeListTypeByte = 150;
213 static const unsigned char kIndexFreeListTypeByte = 151;
214 static const unsigned char kObjectStoreNamesTypeByte = 200;
215 static const unsigned char kIndexNamesKeyTypeByte = 201;
217 static const unsigned char kObjectMetaDataTypeMaximum = 255;
218 static const unsigned char kIndexMetaDataTypeMaximum = 255;
220 const unsigned char kMinimumIndexId = 30;
222 inline void EncodeIntSafely(int64 nParam, int64 max, std::string* into) {
223 DCHECK_LE(nParam, max);
224 return EncodeInt(nParam, into);
227 std::string MaxIDBKey() {
228 std::string ret;
229 EncodeByte(kIndexedDBKeyNullTypeByte, &ret);
230 return ret;
233 std::string MinIDBKey() {
234 std::string ret;
235 EncodeByte(kIndexedDBKeyMinKeyTypeByte, &ret);
236 return ret;
239 void EncodeByte(unsigned char value, std::string* into) {
240 into->push_back(value);
243 void EncodeBool(bool value, std::string* into) {
244 into->push_back(value ? 1 : 0);
247 void EncodeInt(int64 value, std::string* into) {
248 #ifndef NDEBUG
249 // Exercised by unit tests in debug only.
250 DCHECK_GE(value, 0);
251 #endif
252 uint64 n = static_cast<uint64>(value);
254 do {
255 unsigned char c = n;
256 into->push_back(c);
257 n >>= 8;
258 } while (n);
261 void EncodeVarInt(int64 value, std::string* into) {
262 #ifndef NDEBUG
263 // Exercised by unit tests in debug only.
264 DCHECK_GE(value, 0);
265 #endif
266 uint64 n = static_cast<uint64>(value);
268 do {
269 unsigned char c = n & 0x7f;
270 n >>= 7;
271 if (n)
272 c |= 0x80;
273 into->push_back(c);
274 } while (n);
277 void EncodeString(const base::string16& value, std::string* into) {
278 if (value.empty())
279 return;
280 // Backing store is UTF-16BE, convert from host endianness.
281 size_t length = value.length();
282 size_t current = into->size();
283 into->resize(into->size() + length * sizeof(base::char16));
285 const base::char16* src = value.c_str();
286 base::char16* dst =
287 reinterpret_cast<base::char16*>(&*into->begin() + current);
288 for (unsigned i = 0; i < length; ++i)
289 *dst++ = htons(*src++);
292 void EncodeBinary(const std::string& value, std::string* into) {
293 EncodeVarInt(value.length(), into);
294 into->append(value.begin(), value.end());
295 DCHECK(into->size() >= value.size());
298 void EncodeStringWithLength(const base::string16& value, std::string* into) {
299 EncodeVarInt(value.length(), into);
300 EncodeString(value, into);
303 void EncodeDouble(double value, std::string* into) {
304 // This always has host endianness.
305 const char* p = reinterpret_cast<char*>(&value);
306 into->insert(into->end(), p, p + sizeof(value));
309 void EncodeIDBKey(const IndexedDBKey& value, std::string* into) {
310 size_t previous_size = into->size();
311 DCHECK(value.IsValid());
312 switch (value.type()) {
313 case WebIDBKeyTypeArray: {
314 EncodeByte(kIndexedDBKeyArrayTypeByte, into);
315 size_t length = value.array().size();
316 EncodeVarInt(length, into);
317 for (size_t i = 0; i < length; ++i)
318 EncodeIDBKey(value.array()[i], into);
319 DCHECK_GT(into->size(), previous_size);
320 return;
322 case WebIDBKeyTypeBinary:
323 EncodeByte(kIndexedDBKeyBinaryTypeByte, into);
324 EncodeBinary(value.binary(), into);
325 DCHECK_GT(into->size(), previous_size);
326 return;
327 case WebIDBKeyTypeString:
328 EncodeByte(kIndexedDBKeyStringTypeByte, into);
329 EncodeStringWithLength(value.string(), into);
330 DCHECK_GT(into->size(), previous_size);
331 return;
332 case WebIDBKeyTypeDate:
333 EncodeByte(kIndexedDBKeyDateTypeByte, into);
334 EncodeDouble(value.date(), into);
335 DCHECK_EQ(9u, static_cast<size_t>(into->size() - previous_size));
336 return;
337 case WebIDBKeyTypeNumber:
338 EncodeByte(kIndexedDBKeyNumberTypeByte, into);
339 EncodeDouble(value.number(), into);
340 DCHECK_EQ(9u, static_cast<size_t>(into->size() - previous_size));
341 return;
342 case WebIDBKeyTypeNull:
343 case WebIDBKeyTypeInvalid:
344 case WebIDBKeyTypeMin:
345 default:
346 NOTREACHED();
347 EncodeByte(kIndexedDBKeyNullTypeByte, into);
348 return;
352 void EncodeIDBKeyPath(const IndexedDBKeyPath& value, std::string* into) {
353 // May be typed, or may be a raw string. An invalid leading
354 // byte is used to identify typed coding. New records are
355 // always written as typed.
356 EncodeByte(kIndexedDBKeyPathTypeCodedByte1, into);
357 EncodeByte(kIndexedDBKeyPathTypeCodedByte2, into);
358 EncodeByte(static_cast<char>(value.type()), into);
359 switch (value.type()) {
360 case WebIDBKeyPathTypeNull:
361 break;
362 case WebIDBKeyPathTypeString: {
363 EncodeStringWithLength(value.string(), into);
364 break;
366 case WebIDBKeyPathTypeArray: {
367 const std::vector<base::string16>& array = value.array();
368 size_t count = array.size();
369 EncodeVarInt(count, into);
370 for (size_t i = 0; i < count; ++i) {
371 EncodeStringWithLength(array[i], into);
373 break;
378 bool DecodeByte(StringPiece* slice, unsigned char* value) {
379 if (slice->empty())
380 return false;
382 *value = (*slice)[0];
383 slice->remove_prefix(1);
384 return true;
387 bool DecodeBool(StringPiece* slice, bool* value) {
388 if (slice->empty())
389 return false;
391 *value = !!(*slice)[0];
392 slice->remove_prefix(1);
393 return true;
396 bool DecodeInt(StringPiece* slice, int64* value) {
397 if (slice->empty())
398 return false;
400 StringPiece::const_iterator it = slice->begin();
401 int shift = 0;
402 int64 ret = 0;
403 while (it != slice->end()) {
404 unsigned char c = *it++;
405 ret |= static_cast<int64>(c) << shift;
406 shift += 8;
408 *value = ret;
409 slice->remove_prefix(it - slice->begin());
410 return true;
413 bool DecodeVarInt(StringPiece* slice, int64* value) {
414 if (slice->empty())
415 return false;
417 StringPiece::const_iterator it = slice->begin();
418 int shift = 0;
419 int64 ret = 0;
420 do {
421 if (it == slice->end())
422 return false;
424 unsigned char c = *it;
425 ret |= static_cast<int64>(c & 0x7f) << shift;
426 shift += 7;
427 } while (*it++ & 0x80);
428 *value = ret;
429 slice->remove_prefix(it - slice->begin());
430 return true;
433 bool DecodeString(StringPiece* slice, base::string16* value) {
434 if (slice->empty()) {
435 value->clear();
436 return true;
439 // Backing store is UTF-16BE, convert to host endianness.
440 DCHECK(!(slice->size() % sizeof(base::char16)));
441 size_t length = slice->size() / sizeof(base::char16);
442 base::string16 decoded;
443 decoded.reserve(length);
444 const base::char16* encoded =
445 reinterpret_cast<const base::char16*>(slice->begin());
446 for (unsigned i = 0; i < length; ++i)
447 decoded.push_back(ntohs(*encoded++));
449 *value = decoded;
450 slice->remove_prefix(length * sizeof(base::char16));
451 return true;
454 bool DecodeStringWithLength(StringPiece* slice, base::string16* value) {
455 if (slice->empty())
456 return false;
458 int64 length = 0;
459 if (!DecodeVarInt(slice, &length) || length < 0)
460 return false;
461 size_t bytes = length * sizeof(base::char16);
462 if (slice->size() < bytes)
463 return false;
465 StringPiece subpiece(slice->begin(), bytes);
466 slice->remove_prefix(bytes);
467 if (!DecodeString(&subpiece, value))
468 return false;
470 return true;
473 bool DecodeBinary(StringPiece* slice, std::string* value) {
474 if (slice->empty())
475 return false;
477 int64 length = 0;
478 if (!DecodeVarInt(slice, &length) || length < 0)
479 return false;
480 size_t size = length;
481 if (slice->size() < size)
482 return false;
484 value->assign(slice->begin(), size);
485 slice->remove_prefix(size);
486 return true;
489 bool DecodeIDBKey(StringPiece* slice, scoped_ptr<IndexedDBKey>* value) {
490 if (slice->empty())
491 return false;
493 unsigned char type = (*slice)[0];
494 slice->remove_prefix(1);
496 switch (type) {
497 case kIndexedDBKeyNullTypeByte:
498 *value = make_scoped_ptr(new IndexedDBKey());
499 return true;
501 case kIndexedDBKeyArrayTypeByte: {
502 int64 length = 0;
503 if (!DecodeVarInt(slice, &length) || length < 0)
504 return false;
505 IndexedDBKey::KeyArray array;
506 while (length--) {
507 scoped_ptr<IndexedDBKey> key;
508 if (!DecodeIDBKey(slice, &key))
509 return false;
510 array.push_back(*key);
512 *value = make_scoped_ptr(new IndexedDBKey(array));
513 return true;
515 case kIndexedDBKeyBinaryTypeByte: {
516 std::string binary;
517 if (!DecodeBinary(slice, &binary))
518 return false;
519 *value = make_scoped_ptr(new IndexedDBKey(binary));
520 return true;
522 case kIndexedDBKeyStringTypeByte: {
523 base::string16 s;
524 if (!DecodeStringWithLength(slice, &s))
525 return false;
526 *value = make_scoped_ptr(new IndexedDBKey(s));
527 return true;
529 case kIndexedDBKeyDateTypeByte: {
530 double d;
531 if (!DecodeDouble(slice, &d))
532 return false;
533 *value = make_scoped_ptr(new IndexedDBKey(d, WebIDBKeyTypeDate));
534 return true;
536 case kIndexedDBKeyNumberTypeByte: {
537 double d;
538 if (!DecodeDouble(slice, &d))
539 return false;
540 *value = make_scoped_ptr(new IndexedDBKey(d, WebIDBKeyTypeNumber));
541 return true;
545 NOTREACHED();
546 return false;
549 bool DecodeDouble(StringPiece* slice, double* value) {
550 if (slice->size() < sizeof(*value))
551 return false;
553 memcpy(value, slice->begin(), sizeof(*value));
554 slice->remove_prefix(sizeof(*value));
555 return true;
558 bool DecodeIDBKeyPath(StringPiece* slice, IndexedDBKeyPath* value) {
559 // May be typed, or may be a raw string. An invalid leading
560 // byte sequence is used to identify typed coding. New records are
561 // always written as typed.
562 if (slice->size() < 3 || (*slice)[0] != kIndexedDBKeyPathTypeCodedByte1 ||
563 (*slice)[1] != kIndexedDBKeyPathTypeCodedByte2) {
564 base::string16 s;
565 if (!DecodeString(slice, &s))
566 return false;
567 *value = IndexedDBKeyPath(s);
568 return true;
571 slice->remove_prefix(2);
572 DCHECK(!slice->empty());
573 WebIDBKeyPathType type = static_cast<WebIDBKeyPathType>((*slice)[0]);
574 slice->remove_prefix(1);
576 switch (type) {
577 case WebIDBKeyPathTypeNull:
578 DCHECK(slice->empty());
579 *value = IndexedDBKeyPath();
580 return true;
581 case WebIDBKeyPathTypeString: {
582 base::string16 string;
583 if (!DecodeStringWithLength(slice, &string))
584 return false;
585 DCHECK(slice->empty());
586 *value = IndexedDBKeyPath(string);
587 return true;
589 case WebIDBKeyPathTypeArray: {
590 std::vector<base::string16> array;
591 int64 count;
592 if (!DecodeVarInt(slice, &count))
593 return false;
594 DCHECK_GE(count, 0);
595 while (count--) {
596 base::string16 string;
597 if (!DecodeStringWithLength(slice, &string))
598 return false;
599 array.push_back(string);
601 DCHECK(slice->empty());
602 *value = IndexedDBKeyPath(array);
603 return true;
606 NOTREACHED();
607 return false;
610 bool ConsumeEncodedIDBKey(StringPiece* slice) {
611 unsigned char type = (*slice)[0];
612 slice->remove_prefix(1);
614 switch (type) {
615 case kIndexedDBKeyNullTypeByte:
616 case kIndexedDBKeyMinKeyTypeByte:
617 return true;
618 case kIndexedDBKeyArrayTypeByte: {
619 int64 length;
620 if (!DecodeVarInt(slice, &length))
621 return false;
622 while (length--) {
623 if (!ConsumeEncodedIDBKey(slice))
624 return false;
626 return true;
628 case kIndexedDBKeyBinaryTypeByte: {
629 int64 length = 0;
630 if (!DecodeVarInt(slice, &length) || length < 0)
631 return false;
632 if (slice->size() < static_cast<size_t>(length))
633 return false;
634 slice->remove_prefix(length);
635 return true;
637 case kIndexedDBKeyStringTypeByte: {
638 int64 length = 0;
639 if (!DecodeVarInt(slice, &length) || length < 0)
640 return false;
641 if (slice->size() < static_cast<size_t>(length) * sizeof(base::char16))
642 return false;
643 slice->remove_prefix(length * sizeof(base::char16));
644 return true;
646 case kIndexedDBKeyDateTypeByte:
647 case kIndexedDBKeyNumberTypeByte:
648 if (slice->size() < sizeof(double))
649 return false;
650 slice->remove_prefix(sizeof(double));
651 return true;
653 NOTREACHED();
654 return false;
657 bool ExtractEncodedIDBKey(StringPiece* slice, std::string* result) {
658 const char* start = slice->begin();
659 if (!ConsumeEncodedIDBKey(slice))
660 return false;
662 if (result)
663 result->assign(start, slice->begin());
664 return true;
667 static WebIDBKeyType KeyTypeByteToKeyType(unsigned char type) {
668 switch (type) {
669 case kIndexedDBKeyNullTypeByte:
670 return WebIDBKeyTypeInvalid;
671 case kIndexedDBKeyArrayTypeByte:
672 return WebIDBKeyTypeArray;
673 case kIndexedDBKeyBinaryTypeByte:
674 return WebIDBKeyTypeBinary;
675 case kIndexedDBKeyStringTypeByte:
676 return WebIDBKeyTypeString;
677 case kIndexedDBKeyDateTypeByte:
678 return WebIDBKeyTypeDate;
679 case kIndexedDBKeyNumberTypeByte:
680 return WebIDBKeyTypeNumber;
681 case kIndexedDBKeyMinKeyTypeByte:
682 return WebIDBKeyTypeMin;
685 NOTREACHED();
686 return WebIDBKeyTypeInvalid;
689 int CompareEncodedStringsWithLength(StringPiece* slice1,
690 StringPiece* slice2,
691 bool* ok) {
692 int64 len1, len2;
693 if (!DecodeVarInt(slice1, &len1) || !DecodeVarInt(slice2, &len2)) {
694 *ok = false;
695 return 0;
697 DCHECK_GE(len1, 0);
698 DCHECK_GE(len2, 0);
699 if (len1 < 0 || len2 < 0) {
700 *ok = false;
701 return 0;
703 DCHECK_GE(slice1->size(), len1 * sizeof(base::char16));
704 DCHECK_GE(slice2->size(), len2 * sizeof(base::char16));
705 if (slice1->size() < len1 * sizeof(base::char16) ||
706 slice2->size() < len2 * sizeof(base::char16)) {
707 *ok = false;
708 return 0;
711 // Extract the string data, and advance the passed slices.
712 StringPiece string1(slice1->begin(), len1 * sizeof(base::char16));
713 StringPiece string2(slice2->begin(), len2 * sizeof(base::char16));
714 slice1->remove_prefix(len1 * sizeof(base::char16));
715 slice2->remove_prefix(len2 * sizeof(base::char16));
717 *ok = true;
718 // Strings are UTF-16BE encoded, so a simple memcmp is sufficient.
719 return string1.compare(string2);
722 int CompareEncodedBinary(StringPiece* slice1,
723 StringPiece* slice2,
724 bool* ok) {
725 int64 len1, len2;
726 if (!DecodeVarInt(slice1, &len1) || !DecodeVarInt(slice2, &len2)) {
727 *ok = false;
728 return 0;
730 DCHECK_GE(len1, 0);
731 DCHECK_GE(len2, 0);
732 if (len1 < 0 || len2 < 0) {
733 *ok = false;
734 return 0;
736 size_t size1 = len1;
737 size_t size2 = len2;
739 DCHECK_GE(slice1->size(), size1);
740 DCHECK_GE(slice2->size(), size2);
741 if (slice1->size() < size1 || slice2->size() < size2) {
742 *ok = false;
743 return 0;
746 // Extract the binary data, and advance the passed slices.
747 StringPiece binary1(slice1->begin(), size1);
748 StringPiece binary2(slice2->begin(), size2);
749 slice1->remove_prefix(size1);
750 slice2->remove_prefix(size2);
752 *ok = true;
753 // This is the same as a memcmp()
754 return binary1.compare(binary2);
757 static int CompareInts(int64 a, int64 b) {
758 #ifndef NDEBUG
759 // Exercised by unit tests in debug only.
760 DCHECK_GE(a, 0);
761 DCHECK_GE(b, 0);
762 #endif
763 int64 diff = a - b;
764 if (diff < 0)
765 return -1;
766 if (diff > 0)
767 return 1;
768 return 0;
771 static inline int CompareSizes(size_t a, size_t b) {
772 if (a > b)
773 return 1;
774 if (b > a)
775 return -1;
776 return 0;
779 static int CompareTypes(WebIDBKeyType a, WebIDBKeyType b) { return b - a; }
781 int CompareEncodedIDBKeys(StringPiece* slice_a,
782 StringPiece* slice_b,
783 bool* ok) {
784 DCHECK(!slice_a->empty());
785 DCHECK(!slice_b->empty());
786 *ok = true;
787 unsigned char type_a = (*slice_a)[0];
788 unsigned char type_b = (*slice_b)[0];
789 slice_a->remove_prefix(1);
790 slice_b->remove_prefix(1);
792 if (int x = CompareTypes(KeyTypeByteToKeyType(type_a),
793 KeyTypeByteToKeyType(type_b)))
794 return x;
796 switch (type_a) {
797 case kIndexedDBKeyNullTypeByte:
798 case kIndexedDBKeyMinKeyTypeByte:
799 // Null type or max type; no payload to compare.
800 return 0;
801 case kIndexedDBKeyArrayTypeByte: {
802 int64 length_a, length_b;
803 if (!DecodeVarInt(slice_a, &length_a) ||
804 !DecodeVarInt(slice_b, &length_b)) {
805 *ok = false;
806 return 0;
808 for (int64 i = 0; i < length_a && i < length_b; ++i) {
809 int result = CompareEncodedIDBKeys(slice_a, slice_b, ok);
810 if (!*ok || result)
811 return result;
813 return length_a - length_b;
815 case kIndexedDBKeyBinaryTypeByte:
816 return CompareEncodedBinary(slice_a, slice_b, ok);
817 case kIndexedDBKeyStringTypeByte:
818 return CompareEncodedStringsWithLength(slice_a, slice_b, ok);
819 case kIndexedDBKeyDateTypeByte:
820 case kIndexedDBKeyNumberTypeByte: {
821 double d, e;
822 if (!DecodeDouble(slice_a, &d) || !DecodeDouble(slice_b, &e)) {
823 *ok = false;
824 return 0;
826 if (d < e)
827 return -1;
828 if (d > e)
829 return 1;
830 return 0;
834 NOTREACHED();
835 return 0;
838 namespace {
840 template <typename KeyType>
841 int Compare(const StringPiece& a,
842 const StringPiece& b,
843 bool only_compare_index_keys,
844 bool* ok) {
845 KeyType key_a;
846 KeyType key_b;
848 StringPiece slice_a(a);
849 if (!KeyType::Decode(&slice_a, &key_a)) {
850 *ok = false;
851 return 0;
853 StringPiece slice_b(b);
854 if (!KeyType::Decode(&slice_b, &key_b)) {
855 *ok = false;
856 return 0;
859 *ok = true;
860 return key_a.Compare(key_b);
863 template <typename KeyType>
864 int CompareSuffix(StringPiece* a,
865 StringPiece* b,
866 bool only_compare_index_keys,
867 bool* ok) {
868 NOTREACHED();
869 return 0;
872 template <>
873 int CompareSuffix<ExistsEntryKey>(StringPiece* slice_a,
874 StringPiece* slice_b,
875 bool only_compare_index_keys,
876 bool* ok) {
877 DCHECK(!slice_a->empty());
878 DCHECK(!slice_b->empty());
879 return CompareEncodedIDBKeys(slice_a, slice_b, ok);
882 template <>
883 int CompareSuffix<ObjectStoreDataKey>(StringPiece* slice_a,
884 StringPiece* slice_b,
885 bool only_compare_index_keys,
886 bool* ok) {
887 return CompareEncodedIDBKeys(slice_a, slice_b, ok);
890 template <>
891 int CompareSuffix<BlobEntryKey>(StringPiece* slice_a,
892 StringPiece* slice_b,
893 bool only_compare_index_keys,
894 bool* ok) {
895 return CompareEncodedIDBKeys(slice_a, slice_b, ok);
898 template <>
899 int CompareSuffix<IndexDataKey>(StringPiece* slice_a,
900 StringPiece* slice_b,
901 bool only_compare_index_keys,
902 bool* ok) {
903 // index key
904 int result = CompareEncodedIDBKeys(slice_a, slice_b, ok);
905 if (!*ok || result)
906 return result;
907 if (only_compare_index_keys)
908 return 0;
910 // sequence number [optional]
911 int64 sequence_number_a = -1;
912 int64 sequence_number_b = -1;
913 if (!slice_a->empty() && !DecodeVarInt(slice_a, &sequence_number_a))
914 return 0;
915 if (!slice_b->empty() && !DecodeVarInt(slice_b, &sequence_number_b))
916 return 0;
918 if (slice_a->empty() || slice_b->empty())
919 return CompareSizes(slice_a->size(), slice_b->size());
921 // primary key [optional]
922 result = CompareEncodedIDBKeys(slice_a, slice_b, ok);
923 if (!*ok || result)
924 return result;
926 return CompareInts(sequence_number_a, sequence_number_b);
929 int Compare(const StringPiece& a,
930 const StringPiece& b,
931 bool only_compare_index_keys,
932 bool* ok) {
933 StringPiece slice_a(a);
934 StringPiece slice_b(b);
935 KeyPrefix prefix_a;
936 KeyPrefix prefix_b;
937 bool ok_a = KeyPrefix::Decode(&slice_a, &prefix_a);
938 bool ok_b = KeyPrefix::Decode(&slice_b, &prefix_b);
939 DCHECK(ok_a);
940 DCHECK(ok_b);
941 if (!ok_a || !ok_b) {
942 *ok = false;
943 return 0;
946 *ok = true;
947 if (int x = prefix_a.Compare(prefix_b))
948 return x;
950 switch (prefix_a.type()) {
951 case KeyPrefix::GLOBAL_METADATA: {
952 DCHECK(!slice_a.empty());
953 DCHECK(!slice_b.empty());
955 unsigned char type_byte_a;
956 if (!DecodeByte(&slice_a, &type_byte_a)) {
957 *ok = false;
958 return 0;
961 unsigned char type_byte_b;
962 if (!DecodeByte(&slice_b, &type_byte_b)) {
963 *ok = false;
964 return 0;
967 if (int x = type_byte_a - type_byte_b)
968 return x;
969 if (type_byte_a < kMaxSimpleGlobalMetaDataTypeByte)
970 return 0;
972 // Compare<> is used (which re-decodes the prefix) rather than an
973 // specialized CompareSuffix<> because metadata is relatively uncommon
974 // in the database.
976 if (type_byte_a == kDatabaseFreeListTypeByte) {
977 // TODO(jsbell): No need to pass only_compare_index_keys through here.
978 return Compare<DatabaseFreeListKey>(a, b, only_compare_index_keys, ok);
980 if (type_byte_a == kDatabaseNameTypeByte) {
981 return Compare<DatabaseNameKey>(
982 a, b, /*only_compare_index_keys*/ false, ok);
984 break;
987 case KeyPrefix::DATABASE_METADATA: {
988 DCHECK(!slice_a.empty());
989 DCHECK(!slice_b.empty());
991 unsigned char type_byte_a;
992 if (!DecodeByte(&slice_a, &type_byte_a)) {
993 *ok = false;
994 return 0;
997 unsigned char type_byte_b;
998 if (!DecodeByte(&slice_b, &type_byte_b)) {
999 *ok = false;
1000 return 0;
1003 if (int x = type_byte_a - type_byte_b)
1004 return x;
1005 if (type_byte_a < DatabaseMetaDataKey::MAX_SIMPLE_METADATA_TYPE)
1006 return 0;
1008 // Compare<> is used (which re-decodes the prefix) rather than an
1009 // specialized CompareSuffix<> because metadata is relatively uncommon
1010 // in the database.
1012 if (type_byte_a == kObjectStoreMetaDataTypeByte) {
1013 // TODO(jsbell): No need to pass only_compare_index_keys through here.
1014 return Compare<ObjectStoreMetaDataKey>(
1015 a, b, only_compare_index_keys, ok);
1017 if (type_byte_a == kIndexMetaDataTypeByte) {
1018 return Compare<IndexMetaDataKey>(
1019 a, b, /*only_compare_index_keys*/ false, ok);
1021 if (type_byte_a == kObjectStoreFreeListTypeByte) {
1022 return Compare<ObjectStoreFreeListKey>(
1023 a, b, only_compare_index_keys, ok);
1025 if (type_byte_a == kIndexFreeListTypeByte) {
1026 return Compare<IndexFreeListKey>(
1027 a, b, /*only_compare_index_keys*/ false, ok);
1029 if (type_byte_a == kObjectStoreNamesTypeByte) {
1030 // TODO(jsbell): No need to pass only_compare_index_keys through here.
1031 return Compare<ObjectStoreNamesKey>(
1032 a, b, only_compare_index_keys, ok);
1034 if (type_byte_a == kIndexNamesKeyTypeByte) {
1035 return Compare<IndexNamesKey>(
1036 a, b, /*only_compare_index_keys*/ false, ok);
1038 break;
1041 case KeyPrefix::OBJECT_STORE_DATA: {
1042 // Provide a stable ordering for invalid data.
1043 if (slice_a.empty() || slice_b.empty())
1044 return CompareSizes(slice_a.size(), slice_b.size());
1046 return CompareSuffix<ObjectStoreDataKey>(
1047 &slice_a, &slice_b, /*only_compare_index_keys*/ false, ok);
1050 case KeyPrefix::EXISTS_ENTRY: {
1051 // Provide a stable ordering for invalid data.
1052 if (slice_a.empty() || slice_b.empty())
1053 return CompareSizes(slice_a.size(), slice_b.size());
1055 return CompareSuffix<ExistsEntryKey>(
1056 &slice_a, &slice_b, /*only_compare_index_keys*/ false, ok);
1059 case KeyPrefix::BLOB_ENTRY: {
1060 // Provide a stable ordering for invalid data.
1061 if (slice_a.empty() || slice_b.empty())
1062 return CompareSizes(slice_a.size(), slice_b.size());
1064 return CompareSuffix<BlobEntryKey>(
1065 &slice_a, &slice_b, /*only_compare_index_keys*/ false, ok);
1068 case KeyPrefix::INDEX_DATA: {
1069 // Provide a stable ordering for invalid data.
1070 if (slice_a.empty() || slice_b.empty())
1071 return CompareSizes(slice_a.size(), slice_b.size());
1073 return CompareSuffix<IndexDataKey>(
1074 &slice_a, &slice_b, only_compare_index_keys, ok);
1077 case KeyPrefix::INVALID_TYPE:
1078 break;
1081 NOTREACHED();
1082 *ok = false;
1083 return 0;
1086 } // namespace
1088 int Compare(const StringPiece& a,
1089 const StringPiece& b,
1090 bool only_compare_index_keys) {
1091 bool ok;
1092 int result = Compare(a, b, only_compare_index_keys, &ok);
1093 DCHECK(ok);
1094 if (!ok)
1095 return 0;
1096 return result;
1099 KeyPrefix::KeyPrefix()
1100 : database_id_(INVALID_TYPE),
1101 object_store_id_(INVALID_TYPE),
1102 index_id_(INVALID_TYPE) {}
1104 KeyPrefix::KeyPrefix(int64 database_id)
1105 : database_id_(database_id), object_store_id_(0), index_id_(0) {
1106 DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
1109 KeyPrefix::KeyPrefix(int64 database_id, int64 object_store_id)
1110 : database_id_(database_id),
1111 object_store_id_(object_store_id),
1112 index_id_(0) {
1113 DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
1114 DCHECK(KeyPrefix::IsValidObjectStoreId(object_store_id));
1117 KeyPrefix::KeyPrefix(int64 database_id, int64 object_store_id, int64 index_id)
1118 : database_id_(database_id),
1119 object_store_id_(object_store_id),
1120 index_id_(index_id) {
1121 DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
1122 DCHECK(KeyPrefix::IsValidObjectStoreId(object_store_id));
1123 DCHECK(KeyPrefix::IsValidIndexId(index_id));
1126 KeyPrefix::KeyPrefix(enum Type type,
1127 int64 database_id,
1128 int64 object_store_id,
1129 int64 index_id)
1130 : database_id_(database_id),
1131 object_store_id_(object_store_id),
1132 index_id_(index_id) {
1133 DCHECK_EQ(type, INVALID_TYPE);
1134 DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
1135 DCHECK(KeyPrefix::IsValidObjectStoreId(object_store_id));
1138 KeyPrefix KeyPrefix::CreateWithSpecialIndex(int64 database_id,
1139 int64 object_store_id,
1140 int64 index_id) {
1141 DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
1142 DCHECK(KeyPrefix::IsValidObjectStoreId(object_store_id));
1143 DCHECK(index_id);
1144 return KeyPrefix(INVALID_TYPE, database_id, object_store_id, index_id);
1147 bool KeyPrefix::IsValidDatabaseId(int64 database_id) {
1148 return (database_id > 0) && (database_id < KeyPrefix::kMaxDatabaseId);
1151 bool KeyPrefix::IsValidObjectStoreId(int64 object_store_id) {
1152 return (object_store_id > 0) &&
1153 (object_store_id < KeyPrefix::kMaxObjectStoreId);
1156 bool KeyPrefix::IsValidIndexId(int64 index_id) {
1157 return (index_id >= kMinimumIndexId) && (index_id < KeyPrefix::kMaxIndexId);
1160 bool KeyPrefix::Decode(StringPiece* slice, KeyPrefix* result) {
1161 unsigned char first_byte;
1162 if (!DecodeByte(slice, &first_byte))
1163 return false;
1165 size_t database_id_bytes = ((first_byte >> 5) & 0x7) + 1;
1166 size_t object_store_id_bytes = ((first_byte >> 2) & 0x7) + 1;
1167 size_t index_id_bytes = (first_byte & 0x3) + 1;
1169 if (database_id_bytes + object_store_id_bytes + index_id_bytes >
1170 slice->size())
1171 return false;
1174 StringPiece tmp(slice->begin(), database_id_bytes);
1175 if (!DecodeInt(&tmp, &result->database_id_))
1176 return false;
1178 slice->remove_prefix(database_id_bytes);
1180 StringPiece tmp(slice->begin(), object_store_id_bytes);
1181 if (!DecodeInt(&tmp, &result->object_store_id_))
1182 return false;
1184 slice->remove_prefix(object_store_id_bytes);
1186 StringPiece tmp(slice->begin(), index_id_bytes);
1187 if (!DecodeInt(&tmp, &result->index_id_))
1188 return false;
1190 slice->remove_prefix(index_id_bytes);
1191 return true;
1194 std::string KeyPrefix::EncodeEmpty() {
1195 const std::string result(4, 0);
1196 DCHECK(EncodeInternal(0, 0, 0) == std::string(4, 0));
1197 return result;
1200 std::string KeyPrefix::Encode() const {
1201 DCHECK(database_id_ != kInvalidId);
1202 DCHECK(object_store_id_ != kInvalidId);
1203 DCHECK(index_id_ != kInvalidId);
1204 return EncodeInternal(database_id_, object_store_id_, index_id_);
1207 std::string KeyPrefix::EncodeInternal(int64 database_id,
1208 int64 object_store_id,
1209 int64 index_id) {
1210 std::string database_id_string;
1211 std::string object_store_id_string;
1212 std::string index_id_string;
1214 EncodeIntSafely(database_id, kMaxDatabaseId, &database_id_string);
1215 EncodeIntSafely(object_store_id, kMaxObjectStoreId, &object_store_id_string);
1216 EncodeIntSafely(index_id, kMaxIndexId, &index_id_string);
1218 DCHECK(database_id_string.size() <= kMaxDatabaseIdSizeBytes);
1219 DCHECK(object_store_id_string.size() <= kMaxObjectStoreIdSizeBytes);
1220 DCHECK(index_id_string.size() <= kMaxIndexIdSizeBytes);
1222 unsigned char first_byte =
1223 (database_id_string.size() - 1) << (kMaxObjectStoreIdSizeBits +
1224 kMaxIndexIdSizeBits) |
1225 (object_store_id_string.size() - 1) << kMaxIndexIdSizeBits |
1226 (index_id_string.size() - 1);
1227 COMPILE_ASSERT(kMaxDatabaseIdSizeBits + kMaxObjectStoreIdSizeBits +
1228 kMaxIndexIdSizeBits ==
1229 sizeof(first_byte) * 8,
1230 CANT_ENCODE_IDS);
1231 std::string ret;
1232 ret.reserve(kDefaultInlineBufferSize);
1233 ret.push_back(first_byte);
1234 ret.append(database_id_string);
1235 ret.append(object_store_id_string);
1236 ret.append(index_id_string);
1238 DCHECK_LE(ret.size(), kDefaultInlineBufferSize);
1239 return ret;
1242 int KeyPrefix::Compare(const KeyPrefix& other) const {
1243 DCHECK(database_id_ != kInvalidId);
1244 DCHECK(object_store_id_ != kInvalidId);
1245 DCHECK(index_id_ != kInvalidId);
1247 if (database_id_ != other.database_id_)
1248 return CompareInts(database_id_, other.database_id_);
1249 if (object_store_id_ != other.object_store_id_)
1250 return CompareInts(object_store_id_, other.object_store_id_);
1251 if (index_id_ != other.index_id_)
1252 return CompareInts(index_id_, other.index_id_);
1253 return 0;
1256 KeyPrefix::Type KeyPrefix::type() const {
1257 DCHECK(database_id_ != kInvalidId);
1258 DCHECK(object_store_id_ != kInvalidId);
1259 DCHECK(index_id_ != kInvalidId);
1261 if (!database_id_)
1262 return GLOBAL_METADATA;
1263 if (!object_store_id_)
1264 return DATABASE_METADATA;
1265 if (index_id_ == kObjectStoreDataIndexId)
1266 return OBJECT_STORE_DATA;
1267 if (index_id_ == kExistsEntryIndexId)
1268 return EXISTS_ENTRY;
1269 if (index_id_ == kBlobEntryIndexId)
1270 return BLOB_ENTRY;
1271 if (index_id_ >= kMinimumIndexId)
1272 return INDEX_DATA;
1274 NOTREACHED();
1275 return INVALID_TYPE;
1278 std::string SchemaVersionKey::Encode() {
1279 std::string ret = KeyPrefix::EncodeEmpty();
1280 ret.push_back(kSchemaVersionTypeByte);
1281 return ret;
1284 std::string MaxDatabaseIdKey::Encode() {
1285 std::string ret = KeyPrefix::EncodeEmpty();
1286 ret.push_back(kMaxDatabaseIdTypeByte);
1287 return ret;
1290 std::string DataVersionKey::Encode() {
1291 std::string ret = KeyPrefix::EncodeEmpty();
1292 ret.push_back(kDataVersionTypeByte);
1293 return ret;
1296 std::string BlobJournalKey::Encode() {
1297 std::string ret = KeyPrefix::EncodeEmpty();
1298 ret.push_back(kBlobJournalTypeByte);
1299 return ret;
1302 std::string LiveBlobJournalKey::Encode() {
1303 std::string ret = KeyPrefix::EncodeEmpty();
1304 ret.push_back(kLiveBlobJournalTypeByte);
1305 return ret;
1308 DatabaseFreeListKey::DatabaseFreeListKey() : database_id_(-1) {}
1310 bool DatabaseFreeListKey::Decode(StringPiece* slice,
1311 DatabaseFreeListKey* result) {
1312 KeyPrefix prefix;
1313 if (!KeyPrefix::Decode(slice, &prefix))
1314 return false;
1315 DCHECK(!prefix.database_id_);
1316 DCHECK(!prefix.object_store_id_);
1317 DCHECK(!prefix.index_id_);
1318 unsigned char type_byte = 0;
1319 if (!DecodeByte(slice, &type_byte))
1320 return false;
1321 DCHECK_EQ(type_byte, kDatabaseFreeListTypeByte);
1322 if (!DecodeVarInt(slice, &result->database_id_))
1323 return false;
1324 return true;
1327 std::string DatabaseFreeListKey::Encode(int64 database_id) {
1328 std::string ret = KeyPrefix::EncodeEmpty();
1329 ret.push_back(kDatabaseFreeListTypeByte);
1330 EncodeVarInt(database_id, &ret);
1331 return ret;
1334 std::string DatabaseFreeListKey::EncodeMaxKey() {
1335 return Encode(std::numeric_limits<int64>::max());
1338 int64 DatabaseFreeListKey::DatabaseId() const {
1339 DCHECK_GE(database_id_, 0);
1340 return database_id_;
1343 int DatabaseFreeListKey::Compare(const DatabaseFreeListKey& other) const {
1344 DCHECK_GE(database_id_, 0);
1345 return CompareInts(database_id_, other.database_id_);
1348 bool DatabaseNameKey::Decode(StringPiece* slice, DatabaseNameKey* result) {
1349 KeyPrefix prefix;
1350 if (!KeyPrefix::Decode(slice, &prefix))
1351 return false;
1352 DCHECK(!prefix.database_id_);
1353 DCHECK(!prefix.object_store_id_);
1354 DCHECK(!prefix.index_id_);
1355 unsigned char type_byte = 0;
1356 if (!DecodeByte(slice, &type_byte))
1357 return false;
1358 DCHECK_EQ(type_byte, kDatabaseNameTypeByte);
1359 if (!DecodeStringWithLength(slice, &result->origin_))
1360 return false;
1361 if (!DecodeStringWithLength(slice, &result->database_name_))
1362 return false;
1363 return true;
1366 std::string DatabaseNameKey::Encode(const std::string& origin_identifier,
1367 const base::string16& database_name) {
1368 std::string ret = KeyPrefix::EncodeEmpty();
1369 ret.push_back(kDatabaseNameTypeByte);
1370 EncodeStringWithLength(base::ASCIIToUTF16(origin_identifier), &ret);
1371 EncodeStringWithLength(database_name, &ret);
1372 return ret;
1375 std::string DatabaseNameKey::EncodeMinKeyForOrigin(
1376 const std::string& origin_identifier) {
1377 return Encode(origin_identifier, base::string16());
1380 std::string DatabaseNameKey::EncodeStopKeyForOrigin(
1381 const std::string& origin_identifier) {
1382 // just after origin in collation order
1383 return EncodeMinKeyForOrigin(origin_identifier + '\x01');
1386 int DatabaseNameKey::Compare(const DatabaseNameKey& other) {
1387 if (int x = origin_.compare(other.origin_))
1388 return x;
1389 return database_name_.compare(other.database_name_);
1392 bool DatabaseMetaDataKey::IsValidBlobKey(int64 blob_key) {
1393 return blob_key >= kBlobKeyGeneratorInitialNumber;
1396 const int64 DatabaseMetaDataKey::kAllBlobsKey = 1;
1397 const int64 DatabaseMetaDataKey::kBlobKeyGeneratorInitialNumber = 2;
1398 const int64 DatabaseMetaDataKey::kInvalidBlobKey = -1;
1400 std::string DatabaseMetaDataKey::Encode(int64 database_id,
1401 MetaDataType meta_data_type) {
1402 KeyPrefix prefix(database_id);
1403 std::string ret = prefix.Encode();
1404 ret.push_back(meta_data_type);
1405 return ret;
1408 ObjectStoreMetaDataKey::ObjectStoreMetaDataKey()
1409 : object_store_id_(-1), meta_data_type_(-1) {}
1411 bool ObjectStoreMetaDataKey::Decode(StringPiece* slice,
1412 ObjectStoreMetaDataKey* result) {
1413 KeyPrefix prefix;
1414 if (!KeyPrefix::Decode(slice, &prefix))
1415 return false;
1416 DCHECK(prefix.database_id_);
1417 DCHECK(!prefix.object_store_id_);
1418 DCHECK(!prefix.index_id_);
1419 unsigned char type_byte = 0;
1420 if (!DecodeByte(slice, &type_byte))
1421 return false;
1422 DCHECK_EQ(type_byte, kObjectStoreMetaDataTypeByte);
1423 if (!DecodeVarInt(slice, &result->object_store_id_))
1424 return false;
1425 DCHECK(result->object_store_id_);
1426 if (!DecodeByte(slice, &result->meta_data_type_))
1427 return false;
1428 return true;
1431 std::string ObjectStoreMetaDataKey::Encode(int64 database_id,
1432 int64 object_store_id,
1433 unsigned char meta_data_type) {
1434 KeyPrefix prefix(database_id);
1435 std::string ret = prefix.Encode();
1436 ret.push_back(kObjectStoreMetaDataTypeByte);
1437 EncodeVarInt(object_store_id, &ret);
1438 ret.push_back(meta_data_type);
1439 return ret;
1442 std::string ObjectStoreMetaDataKey::EncodeMaxKey(int64 database_id) {
1443 return Encode(database_id,
1444 std::numeric_limits<int64>::max(),
1445 kObjectMetaDataTypeMaximum);
1448 std::string ObjectStoreMetaDataKey::EncodeMaxKey(int64 database_id,
1449 int64 object_store_id) {
1450 return Encode(database_id, object_store_id, kObjectMetaDataTypeMaximum);
1453 int64 ObjectStoreMetaDataKey::ObjectStoreId() const {
1454 DCHECK_GE(object_store_id_, 0);
1455 return object_store_id_;
1457 unsigned char ObjectStoreMetaDataKey::MetaDataType() const {
1458 return meta_data_type_;
1461 int ObjectStoreMetaDataKey::Compare(const ObjectStoreMetaDataKey& other) {
1462 DCHECK_GE(object_store_id_, 0);
1463 if (int x = CompareInts(object_store_id_, other.object_store_id_))
1464 return x;
1465 return meta_data_type_ - other.meta_data_type_;
1468 IndexMetaDataKey::IndexMetaDataKey()
1469 : object_store_id_(-1), index_id_(-1), meta_data_type_(0) {}
1471 bool IndexMetaDataKey::Decode(StringPiece* slice, IndexMetaDataKey* result) {
1472 KeyPrefix prefix;
1473 if (!KeyPrefix::Decode(slice, &prefix))
1474 return false;
1475 DCHECK(prefix.database_id_);
1476 DCHECK(!prefix.object_store_id_);
1477 DCHECK(!prefix.index_id_);
1478 unsigned char type_byte = 0;
1479 if (!DecodeByte(slice, &type_byte))
1480 return false;
1481 DCHECK_EQ(type_byte, kIndexMetaDataTypeByte);
1482 if (!DecodeVarInt(slice, &result->object_store_id_))
1483 return false;
1484 if (!DecodeVarInt(slice, &result->index_id_))
1485 return false;
1486 if (!DecodeByte(slice, &result->meta_data_type_))
1487 return false;
1488 return true;
1491 std::string IndexMetaDataKey::Encode(int64 database_id,
1492 int64 object_store_id,
1493 int64 index_id,
1494 unsigned char meta_data_type) {
1495 KeyPrefix prefix(database_id);
1496 std::string ret = prefix.Encode();
1497 ret.push_back(kIndexMetaDataTypeByte);
1498 EncodeVarInt(object_store_id, &ret);
1499 EncodeVarInt(index_id, &ret);
1500 EncodeByte(meta_data_type, &ret);
1501 return ret;
1504 std::string IndexMetaDataKey::EncodeMaxKey(int64 database_id,
1505 int64 object_store_id) {
1506 return Encode(database_id,
1507 object_store_id,
1508 std::numeric_limits<int64>::max(),
1509 kIndexMetaDataTypeMaximum);
1512 std::string IndexMetaDataKey::EncodeMaxKey(int64 database_id,
1513 int64 object_store_id,
1514 int64 index_id) {
1515 return Encode(
1516 database_id, object_store_id, index_id, kIndexMetaDataTypeMaximum);
1519 int IndexMetaDataKey::Compare(const IndexMetaDataKey& other) {
1520 DCHECK_GE(object_store_id_, 0);
1521 DCHECK_GE(index_id_, 0);
1523 if (int x = CompareInts(object_store_id_, other.object_store_id_))
1524 return x;
1525 if (int x = CompareInts(index_id_, other.index_id_))
1526 return x;
1527 return meta_data_type_ - other.meta_data_type_;
1530 int64 IndexMetaDataKey::IndexId() const {
1531 DCHECK_GE(index_id_, 0);
1532 return index_id_;
1535 ObjectStoreFreeListKey::ObjectStoreFreeListKey() : object_store_id_(-1) {}
1537 bool ObjectStoreFreeListKey::Decode(StringPiece* slice,
1538 ObjectStoreFreeListKey* result) {
1539 KeyPrefix prefix;
1540 if (!KeyPrefix::Decode(slice, &prefix))
1541 return false;
1542 DCHECK(prefix.database_id_);
1543 DCHECK(!prefix.object_store_id_);
1544 DCHECK(!prefix.index_id_);
1545 unsigned char type_byte = 0;
1546 if (!DecodeByte(slice, &type_byte))
1547 return false;
1548 DCHECK_EQ(type_byte, kObjectStoreFreeListTypeByte);
1549 if (!DecodeVarInt(slice, &result->object_store_id_))
1550 return false;
1551 return true;
1554 std::string ObjectStoreFreeListKey::Encode(int64 database_id,
1555 int64 object_store_id) {
1556 KeyPrefix prefix(database_id);
1557 std::string ret = prefix.Encode();
1558 ret.push_back(kObjectStoreFreeListTypeByte);
1559 EncodeVarInt(object_store_id, &ret);
1560 return ret;
1563 std::string ObjectStoreFreeListKey::EncodeMaxKey(int64 database_id) {
1564 return Encode(database_id, std::numeric_limits<int64>::max());
1567 int64 ObjectStoreFreeListKey::ObjectStoreId() const {
1568 DCHECK_GE(object_store_id_, 0);
1569 return object_store_id_;
1572 int ObjectStoreFreeListKey::Compare(const ObjectStoreFreeListKey& other) {
1573 // TODO(jsbell): It may seem strange that we're not comparing database id's,
1574 // but that comparison will have been made earlier.
1575 // We should probably make this more clear, though...
1576 DCHECK_GE(object_store_id_, 0);
1577 return CompareInts(object_store_id_, other.object_store_id_);
1580 IndexFreeListKey::IndexFreeListKey() : object_store_id_(-1), index_id_(-1) {}
1582 bool IndexFreeListKey::Decode(StringPiece* slice, IndexFreeListKey* result) {
1583 KeyPrefix prefix;
1584 if (!KeyPrefix::Decode(slice, &prefix))
1585 return false;
1586 DCHECK(prefix.database_id_);
1587 DCHECK(!prefix.object_store_id_);
1588 DCHECK(!prefix.index_id_);
1589 unsigned char type_byte = 0;
1590 if (!DecodeByte(slice, &type_byte))
1591 return false;
1592 DCHECK_EQ(type_byte, kIndexFreeListTypeByte);
1593 if (!DecodeVarInt(slice, &result->object_store_id_))
1594 return false;
1595 if (!DecodeVarInt(slice, &result->index_id_))
1596 return false;
1597 return true;
1600 std::string IndexFreeListKey::Encode(int64 database_id,
1601 int64 object_store_id,
1602 int64 index_id) {
1603 KeyPrefix prefix(database_id);
1604 std::string ret = prefix.Encode();
1605 ret.push_back(kIndexFreeListTypeByte);
1606 EncodeVarInt(object_store_id, &ret);
1607 EncodeVarInt(index_id, &ret);
1608 return ret;
1611 std::string IndexFreeListKey::EncodeMaxKey(int64 database_id,
1612 int64 object_store_id) {
1613 return Encode(
1614 database_id, object_store_id, std::numeric_limits<int64>::max());
1617 int IndexFreeListKey::Compare(const IndexFreeListKey& other) {
1618 DCHECK_GE(object_store_id_, 0);
1619 DCHECK_GE(index_id_, 0);
1620 if (int x = CompareInts(object_store_id_, other.object_store_id_))
1621 return x;
1622 return CompareInts(index_id_, other.index_id_);
1625 int64 IndexFreeListKey::ObjectStoreId() const {
1626 DCHECK_GE(object_store_id_, 0);
1627 return object_store_id_;
1630 int64 IndexFreeListKey::IndexId() const {
1631 DCHECK_GE(index_id_, 0);
1632 return index_id_;
1635 // TODO(jsbell): We never use this to look up object store ids,
1636 // because a mapping is kept in the IndexedDBDatabase. Can the
1637 // mapping become unreliable? Can we remove this?
1638 bool ObjectStoreNamesKey::Decode(StringPiece* slice,
1639 ObjectStoreNamesKey* result) {
1640 KeyPrefix prefix;
1641 if (!KeyPrefix::Decode(slice, &prefix))
1642 return false;
1643 DCHECK(prefix.database_id_);
1644 DCHECK(!prefix.object_store_id_);
1645 DCHECK(!prefix.index_id_);
1646 unsigned char type_byte = 0;
1647 if (!DecodeByte(slice, &type_byte))
1648 return false;
1649 DCHECK_EQ(type_byte, kObjectStoreNamesTypeByte);
1650 if (!DecodeStringWithLength(slice, &result->object_store_name_))
1651 return false;
1652 return true;
1655 std::string ObjectStoreNamesKey::Encode(
1656 int64 database_id,
1657 const base::string16& object_store_name) {
1658 KeyPrefix prefix(database_id);
1659 std::string ret = prefix.Encode();
1660 ret.push_back(kObjectStoreNamesTypeByte);
1661 EncodeStringWithLength(object_store_name, &ret);
1662 return ret;
1665 int ObjectStoreNamesKey::Compare(const ObjectStoreNamesKey& other) {
1666 return object_store_name_.compare(other.object_store_name_);
1669 IndexNamesKey::IndexNamesKey() : object_store_id_(-1) {}
1671 // TODO(jsbell): We never use this to look up index ids, because a mapping
1672 // is kept at a higher level.
1673 bool IndexNamesKey::Decode(StringPiece* slice, IndexNamesKey* result) {
1674 KeyPrefix prefix;
1675 if (!KeyPrefix::Decode(slice, &prefix))
1676 return false;
1677 DCHECK(prefix.database_id_);
1678 DCHECK(!prefix.object_store_id_);
1679 DCHECK(!prefix.index_id_);
1680 unsigned char type_byte = 0;
1681 if (!DecodeByte(slice, &type_byte))
1682 return false;
1683 DCHECK_EQ(type_byte, kIndexNamesKeyTypeByte);
1684 if (!DecodeVarInt(slice, &result->object_store_id_))
1685 return false;
1686 if (!DecodeStringWithLength(slice, &result->index_name_))
1687 return false;
1688 return true;
1691 std::string IndexNamesKey::Encode(int64 database_id,
1692 int64 object_store_id,
1693 const base::string16& index_name) {
1694 KeyPrefix prefix(database_id);
1695 std::string ret = prefix.Encode();
1696 ret.push_back(kIndexNamesKeyTypeByte);
1697 EncodeVarInt(object_store_id, &ret);
1698 EncodeStringWithLength(index_name, &ret);
1699 return ret;
1702 int IndexNamesKey::Compare(const IndexNamesKey& other) {
1703 DCHECK_GE(object_store_id_, 0);
1704 if (int x = CompareInts(object_store_id_, other.object_store_id_))
1705 return x;
1706 return index_name_.compare(other.index_name_);
1709 ObjectStoreDataKey::ObjectStoreDataKey() {}
1710 ObjectStoreDataKey::~ObjectStoreDataKey() {}
1712 bool ObjectStoreDataKey::Decode(StringPiece* slice,
1713 ObjectStoreDataKey* result) {
1714 KeyPrefix prefix;
1715 if (!KeyPrefix::Decode(slice, &prefix))
1716 return false;
1717 DCHECK(prefix.database_id_);
1718 DCHECK(prefix.object_store_id_);
1719 DCHECK_EQ(prefix.index_id_, kSpecialIndexNumber);
1720 if (!ExtractEncodedIDBKey(slice, &result->encoded_user_key_))
1721 return false;
1722 return true;
1725 std::string ObjectStoreDataKey::Encode(int64 database_id,
1726 int64 object_store_id,
1727 const std::string encoded_user_key) {
1728 KeyPrefix prefix(KeyPrefix::CreateWithSpecialIndex(
1729 database_id, object_store_id, kSpecialIndexNumber));
1730 std::string ret = prefix.Encode();
1731 ret.append(encoded_user_key);
1733 return ret;
1736 std::string ObjectStoreDataKey::Encode(int64 database_id,
1737 int64 object_store_id,
1738 const IndexedDBKey& user_key) {
1739 std::string encoded_key;
1740 EncodeIDBKey(user_key, &encoded_key);
1741 return Encode(database_id, object_store_id, encoded_key);
1744 scoped_ptr<IndexedDBKey> ObjectStoreDataKey::user_key() const {
1745 scoped_ptr<IndexedDBKey> key;
1746 StringPiece slice(encoded_user_key_);
1747 if (!DecodeIDBKey(&slice, &key)) {
1748 // TODO(jsbell): Return error.
1750 return key.Pass();
1753 const int64 ObjectStoreDataKey::kSpecialIndexNumber = kObjectStoreDataIndexId;
1755 ExistsEntryKey::ExistsEntryKey() {}
1756 ExistsEntryKey::~ExistsEntryKey() {}
1758 bool ExistsEntryKey::Decode(StringPiece* slice, ExistsEntryKey* result) {
1759 KeyPrefix prefix;
1760 if (!KeyPrefix::Decode(slice, &prefix))
1761 return false;
1762 DCHECK(prefix.database_id_);
1763 DCHECK(prefix.object_store_id_);
1764 DCHECK_EQ(prefix.index_id_, kSpecialIndexNumber);
1765 if (!ExtractEncodedIDBKey(slice, &result->encoded_user_key_))
1766 return false;
1767 return true;
1770 std::string ExistsEntryKey::Encode(int64 database_id,
1771 int64 object_store_id,
1772 const std::string& encoded_key) {
1773 KeyPrefix prefix(KeyPrefix::CreateWithSpecialIndex(
1774 database_id, object_store_id, kSpecialIndexNumber));
1775 std::string ret = prefix.Encode();
1776 ret.append(encoded_key);
1777 return ret;
1780 std::string ExistsEntryKey::Encode(int64 database_id,
1781 int64 object_store_id,
1782 const IndexedDBKey& user_key) {
1783 std::string encoded_key;
1784 EncodeIDBKey(user_key, &encoded_key);
1785 return Encode(database_id, object_store_id, encoded_key);
1788 scoped_ptr<IndexedDBKey> ExistsEntryKey::user_key() const {
1789 scoped_ptr<IndexedDBKey> key;
1790 StringPiece slice(encoded_user_key_);
1791 if (!DecodeIDBKey(&slice, &key)) {
1792 // TODO(jsbell): Return error.
1794 return key.Pass();
1797 const int64 ExistsEntryKey::kSpecialIndexNumber = kExistsEntryIndexId;
1799 bool BlobEntryKey::Decode(StringPiece* slice, BlobEntryKey* result) {
1800 KeyPrefix prefix;
1801 if (!KeyPrefix::Decode(slice, &prefix))
1802 return false;
1803 DCHECK(prefix.database_id_);
1804 DCHECK(prefix.object_store_id_);
1805 DCHECK_EQ(prefix.index_id_, kSpecialIndexNumber);
1807 if (!ExtractEncodedIDBKey(slice, &result->encoded_user_key_))
1808 return false;
1809 result->database_id_ = prefix.database_id_;
1810 result->object_store_id_ = prefix.object_store_id_;
1812 return true;
1815 bool BlobEntryKey::FromObjectStoreDataKey(StringPiece* slice,
1816 BlobEntryKey* result) {
1817 KeyPrefix prefix;
1818 if (!KeyPrefix::Decode(slice, &prefix))
1819 return false;
1820 DCHECK(prefix.database_id_);
1821 DCHECK(prefix.object_store_id_);
1822 DCHECK_EQ(prefix.index_id_, ObjectStoreDataKey::kSpecialIndexNumber);
1824 if (!ExtractEncodedIDBKey(slice, &result->encoded_user_key_))
1825 return false;
1826 result->database_id_ = prefix.database_id_;
1827 result->object_store_id_ = prefix.object_store_id_;
1828 return true;
1831 std::string BlobEntryKey::ReencodeToObjectStoreDataKey(StringPiece* slice) {
1832 // TODO(ericu): We could be more efficient here, since the suffix is the same.
1833 BlobEntryKey key;
1834 if (!Decode(slice, &key))
1835 return std::string();
1837 return ObjectStoreDataKey::Encode(
1838 key.database_id_, key.object_store_id_, key.encoded_user_key_);
1841 std::string BlobEntryKey::EncodeMinKeyForObjectStore(int64 database_id,
1842 int64 object_store_id) {
1843 // Our implied encoded_user_key_ here is empty, the lowest possible key.
1844 return Encode(database_id, object_store_id, std::string());
1847 std::string BlobEntryKey::EncodeStopKeyForObjectStore(int64 database_id,
1848 int64 object_store_id) {
1849 DCHECK(KeyPrefix::ValidIds(database_id, object_store_id));
1850 KeyPrefix prefix(KeyPrefix::CreateWithSpecialIndex(
1851 database_id, object_store_id, kSpecialIndexNumber + 1));
1852 return prefix.Encode();
1855 std::string BlobEntryKey::Encode() const {
1856 DCHECK(!encoded_user_key_.empty());
1857 return Encode(database_id_, object_store_id_, encoded_user_key_);
1860 std::string BlobEntryKey::Encode(int64 database_id,
1861 int64 object_store_id,
1862 const IndexedDBKey& user_key) {
1863 std::string encoded_key;
1864 EncodeIDBKey(user_key, &encoded_key);
1865 return Encode(database_id, object_store_id, encoded_key);
1868 std::string BlobEntryKey::Encode(int64 database_id,
1869 int64 object_store_id,
1870 const std::string& encoded_user_key) {
1871 DCHECK(KeyPrefix::ValidIds(database_id, object_store_id));
1872 KeyPrefix prefix(KeyPrefix::CreateWithSpecialIndex(
1873 database_id, object_store_id, kSpecialIndexNumber));
1874 return prefix.Encode() + encoded_user_key;
1877 const int64 BlobEntryKey::kSpecialIndexNumber = kBlobEntryIndexId;
1879 IndexDataKey::IndexDataKey()
1880 : database_id_(-1),
1881 object_store_id_(-1),
1882 index_id_(-1),
1883 sequence_number_(-1) {}
1885 IndexDataKey::~IndexDataKey() {}
1887 bool IndexDataKey::Decode(StringPiece* slice, IndexDataKey* result) {
1888 KeyPrefix prefix;
1889 if (!KeyPrefix::Decode(slice, &prefix))
1890 return false;
1891 DCHECK(prefix.database_id_);
1892 DCHECK(prefix.object_store_id_);
1893 DCHECK_GE(prefix.index_id_, kMinimumIndexId);
1894 result->database_id_ = prefix.database_id_;
1895 result->object_store_id_ = prefix.object_store_id_;
1896 result->index_id_ = prefix.index_id_;
1897 result->sequence_number_ = -1;
1898 result->encoded_primary_key_ = MinIDBKey();
1900 if (!ExtractEncodedIDBKey(slice, &result->encoded_user_key_))
1901 return false;
1903 // [optional] sequence number
1904 if (slice->empty())
1905 return true;
1906 if (!DecodeVarInt(slice, &result->sequence_number_))
1907 return false;
1909 // [optional] primary key
1910 if (slice->empty())
1911 return true;
1912 if (!ExtractEncodedIDBKey(slice, &result->encoded_primary_key_))
1913 return false;
1914 return true;
1917 std::string IndexDataKey::Encode(int64 database_id,
1918 int64 object_store_id,
1919 int64 index_id,
1920 const std::string& encoded_user_key,
1921 const std::string& encoded_primary_key,
1922 int64 sequence_number) {
1923 KeyPrefix prefix(database_id, object_store_id, index_id);
1924 std::string ret = prefix.Encode();
1925 ret.append(encoded_user_key);
1926 EncodeVarInt(sequence_number, &ret);
1927 ret.append(encoded_primary_key);
1928 return ret;
1931 std::string IndexDataKey::Encode(int64 database_id,
1932 int64 object_store_id,
1933 int64 index_id,
1934 const IndexedDBKey& user_key) {
1935 std::string encoded_key;
1936 EncodeIDBKey(user_key, &encoded_key);
1937 return Encode(
1938 database_id, object_store_id, index_id, encoded_key, MinIDBKey(), 0);
1941 std::string IndexDataKey::Encode(int64 database_id,
1942 int64 object_store_id,
1943 int64 index_id,
1944 const IndexedDBKey& user_key,
1945 const IndexedDBKey& user_primary_key) {
1946 std::string encoded_key;
1947 EncodeIDBKey(user_key, &encoded_key);
1948 std::string encoded_primary_key;
1949 EncodeIDBKey(user_primary_key, &encoded_primary_key);
1950 return Encode(database_id,
1951 object_store_id,
1952 index_id,
1953 encoded_key,
1954 encoded_primary_key,
1958 std::string IndexDataKey::EncodeMinKey(int64 database_id,
1959 int64 object_store_id,
1960 int64 index_id) {
1961 return Encode(
1962 database_id, object_store_id, index_id, MinIDBKey(), MinIDBKey(), 0);
1965 std::string IndexDataKey::EncodeMaxKey(int64 database_id,
1966 int64 object_store_id,
1967 int64 index_id) {
1968 return Encode(database_id,
1969 object_store_id,
1970 index_id,
1971 MaxIDBKey(),
1972 MaxIDBKey(),
1973 std::numeric_limits<int64>::max());
1976 int64 IndexDataKey::DatabaseId() const {
1977 DCHECK_GE(database_id_, 0);
1978 return database_id_;
1981 int64 IndexDataKey::ObjectStoreId() const {
1982 DCHECK_GE(object_store_id_, 0);
1983 return object_store_id_;
1986 int64 IndexDataKey::IndexId() const {
1987 DCHECK_GE(index_id_, 0);
1988 return index_id_;
1991 scoped_ptr<IndexedDBKey> IndexDataKey::user_key() const {
1992 scoped_ptr<IndexedDBKey> key;
1993 StringPiece slice(encoded_user_key_);
1994 if (!DecodeIDBKey(&slice, &key)) {
1995 // TODO(jsbell): Return error.
1997 return key.Pass();
2000 scoped_ptr<IndexedDBKey> IndexDataKey::primary_key() const {
2001 scoped_ptr<IndexedDBKey> key;
2002 StringPiece slice(encoded_primary_key_);
2003 if (!DecodeIDBKey(&slice, &key)) {
2004 // TODO(jsbell): Return error.
2006 return key.Pass();
2009 } // namespace content