1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// found in the LICENSE file.
4868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/browser/indexed_db/indexed_db_leveldb_coding.h"
6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <iterator>
8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <limits>
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/logging.h"
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h"
12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/strings/utf_string_conversions.h"
13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/sys_byteorder.h"
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/common/indexed_db/indexed_db_key.h"
15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/common/indexed_db/indexed_db_key_path.h"
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// LevelDB Coding Scheme
183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// =====================
193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)//
20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// LevelDB stores key/value pairs. Keys and values are strings of bytes,
217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// normally of type std::string.
22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//
233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// The keys in the backing store are variable-length tuples with different
243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// types of fields. Each key in the backing store starts with a ternary
253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// prefix: (database id, object store id, index id). For each, 0 is reserved
263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// for metadata. See KeyPrefix::Decode() for details of the prefix coding.
273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)//
28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// The prefix makes sure that data for a specific database, object store, and
293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// index are grouped together. The locality is important for performance:
303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// common operations should only need a minimal number of seek operations. For
313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// example, all the metadata for a database is grouped together so that
323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// reading that metadata only requires one seek.
33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//
34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Each key type has a class (in square brackets below) which knows how to
35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// encode, decode, and compare that key type.
36868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//
373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Strings (origins, names, etc) are encoded as UTF-16BE.
38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//
39868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//
403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Global metadata
413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// ---------------
423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// The prefix is <0, 0, 0>, followed by a metadata type byte:
43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//
443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// <0, 0, 0, 0> => backing store schema version [SchemaVersionKey]
453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// <0, 0, 0, 1> => maximum allocated database [MaxDatabaseIdKey]
463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// <0, 0, 0, 2> => SerializedScriptValue version [DataVersionKey]
47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// <0, 0, 0, 3>
48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)//   => Blob journal
49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//     The format of the journal is:
50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//         {database_id (var int), blobKey (var int)}*.
51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)//     If the blobKey is kAllBlobsKey, the whole database should be deleted.
52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)//     [BlobJournalKey]
53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// <0, 0, 0, 4> => Live blob journal; same format. [LiveBlobJournalKey]
543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// <0, 0, 0, 100, database id>
553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)//   => Existence implies the database id is in the free list
563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)//      [DatabaseFreeListKey]
573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// <0, 0, 0, 201, origin, database name> => Database id [DatabaseNameKey]
58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//
59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//
603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Database metadata: [DatabaseMetaDataKey]
613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// ----------------------------------------
623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// The prefix is <database id, 0, 0> followed by a metadata type byte:
63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//
643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// <database id, 0, 0, 0> => origin name
653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// <database id, 0, 0, 1> => database name
663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// <database id, 0, 0, 2> => IDB string version data (obsolete)
673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// <database id, 0, 0, 3> => maximum allocated object store id
683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// <database id, 0, 0, 4> => IDB integer version (var int)
69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// <database id, 0, 0, 5> => blob key generator current number
70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//
71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//
723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Object store metadata: [ObjectStoreMetaDataKey]
733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// -----------------------------------------------
743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// The prefix is <database id, 0, 0>, followed by a type byte (50), then the
753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// object store id (var int), then a metadata type byte.
76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//
773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// <database id, 0, 0, 50, object store id, 0> => object store name
783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// <database id, 0, 0, 50, object store id, 1> => key path
793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// <database id, 0, 0, 50, object store id, 2> => auto increment flag
803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// <database id, 0, 0, 50, object store id, 3> => is evictable
813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// <database id, 0, 0, 50, object store id, 4> => last "version" number
823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// <database id, 0, 0, 50, object store id, 5> => maximum allocated index id
833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// <database id, 0, 0, 50, object store id, 6> => has key path flag (obsolete)
843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// <database id, 0, 0, 50, object store id, 7> => key generator current number
85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//
863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// The key path was originally just a string (#1) or null (identified by flag,
873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// #6). To support null, string, or array the coding is now identified by the
883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// leading bytes in #1 - see EncodeIDBKeyPath.
89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//
903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// The "version" field is used to weed out stale index data. Whenever new
913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// object store data is inserted, it gets a new "version" number, and new
923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// index data is written with this number. When the index is used for
933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// look-ups, entries are validated against the "exists" entries, and records
943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// with old "version" numbers are deleted when they are encountered in
953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// GetPrimaryKeyViaIndex, IndexCursorImpl::LoadCurrentRow and
963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// IndexKeyCursorImpl::LoadCurrentRow.
97868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//
98868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//
993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Index metadata: [IndexMetaDataKey]
1003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// ----------------------------------
1013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// The prefix is <database id, 0, 0>, followed by a type byte (100), then the
1023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// object store id (var int), then the index id (var int), then a metadata
1033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// type byte.
104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//
1053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// <database id, 0, 0, 100, object store id, index id, 0> => index name
1063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// <database id, 0, 0, 100, object store id, index id, 1> => unique flag
1073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// <database id, 0, 0, 100, object store id, index id, 2> => key path
1083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// <database id, 0, 0, 100, object store id, index id, 3> => multi-entry flag
109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//
110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//
1113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Other object store and index metadata
1123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// -------------------------------------
1133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// The prefix is <database id, 0, 0> followed by a type byte. The object
1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// store and index id are variable length integers, the names are variable
1153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// length strings.
116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//
1173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// <database id, 0, 0, 150, object store id>
1183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)//   => existence implies the object store id is in the free list
1193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)//      [ObjectStoreFreeListKey]
1203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// <database id, 0, 0, 151, object store id, index id>
1213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)//   => existence implies the index id is in the free list [IndexFreeListKey]
1223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// <database id, 0, 0, 200, object store name>
1233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)//   => object store id [ObjectStoreNamesKey]
1243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// <database id, 0, 0, 201, object store id, index name>
1253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)//   => index id [IndexNamesKey]
126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//
127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//
1283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Object store data: [ObjectStoreDataKey]
1293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// ---------------------------------------
1303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// The prefix is followed by a type byte and the encoded IDB primary key. The
1313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// data has a "version" prefix followed by the serialized script value.
132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//
1333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// <database id, object store id, 1, user key>
1343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)//   => "version", serialized script value
135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//
136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//
1373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// "Exists" entry: [ExistsEntryKey]
1383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// --------------------------------
1393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// The prefix is followed by a type byte and the encoded IDB primary key.
140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//
1413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// <database id, object store id, 2, user key> => "version"
142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//
143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//
144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Blob entry table: [BlobEntryKey]
145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// --------------------------------
146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)//
147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// The prefix is followed by a type byte and the encoded IDB primary key.
148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)//
149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// <database id, object store id, 3, user key> => array of IndexedDBBlobInfo
150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)//
151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)//
1523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Index data
1533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// ----------
1543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// The prefix is followed by a type byte, the encoded IDB index key, a
1553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// "sequence" number (obsolete; var int), and the encoded IDB primary key.
156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//
1573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// <database id, object store id, index id, index key, sequence number,
1583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)//   primary key> => "version", primary key [IndexDataKey]
159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//
1603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// The sequence number is obsolete; it was used to allow two entries with the
1613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// same user (index) key in non-unique indexes prior to the inclusion of the
1623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// primary key in the data.
1633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
164868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)using base::StringPiece;
165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebIDBKeyType;
166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebIDBKeyTypeArray;
167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebIDBKeyTypeBinary;
168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebIDBKeyTypeDate;
169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebIDBKeyTypeInvalid;
170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebIDBKeyTypeMin;
171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebIDBKeyTypeNull;
172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebIDBKeyTypeNumber;
173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebIDBKeyTypeString;
174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebIDBKeyPathType;
175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebIDBKeyPathTypeArray;
176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebIDBKeyPathTypeNull;
177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebIDBKeyPathTypeString;
178868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace content {
180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// As most of the IndexedDBKeys and encoded values are short, we
182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// initialize some std::vectors with a default inline buffer size to reduce
183a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// the memory re-allocations when the std::vectors are appended.
184868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static const size_t kDefaultInlineBufferSize = 32;
185868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
186868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static const unsigned char kIndexedDBKeyNullTypeByte = 0;
187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static const unsigned char kIndexedDBKeyStringTypeByte = 1;
188868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static const unsigned char kIndexedDBKeyDateTypeByte = 2;
189868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static const unsigned char kIndexedDBKeyNumberTypeByte = 3;
190868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static const unsigned char kIndexedDBKeyArrayTypeByte = 4;
191868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static const unsigned char kIndexedDBKeyMinKeyTypeByte = 5;
192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static const unsigned char kIndexedDBKeyBinaryTypeByte = 6;
193868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
194868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static const unsigned char kIndexedDBKeyPathTypeCodedByte1 = 0;
195868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static const unsigned char kIndexedDBKeyPathTypeCodedByte2 = 0;
196868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
197868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static const unsigned char kObjectStoreDataIndexId = 1;
198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static const unsigned char kExistsEntryIndexId = 2;
199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)static const unsigned char kBlobEntryIndexId = 3;
200868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static const unsigned char kSchemaVersionTypeByte = 0;
202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static const unsigned char kMaxDatabaseIdTypeByte = 1;
203868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static const unsigned char kDataVersionTypeByte = 2;
204a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)static const unsigned char kBlobJournalTypeByte = 3;
205a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)static const unsigned char kLiveBlobJournalTypeByte = 4;
206868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static const unsigned char kMaxSimpleGlobalMetaDataTypeByte =
207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    5;  // Insert before this and increment.
208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static const unsigned char kDatabaseFreeListTypeByte = 100;
209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static const unsigned char kDatabaseNameTypeByte = 201;
210868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
211868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static const unsigned char kObjectStoreMetaDataTypeByte = 50;
212868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static const unsigned char kIndexMetaDataTypeByte = 100;
213868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static const unsigned char kObjectStoreFreeListTypeByte = 150;
214868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static const unsigned char kIndexFreeListTypeByte = 151;
215868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static const unsigned char kObjectStoreNamesTypeByte = 200;
216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static const unsigned char kIndexNamesKeyTypeByte = 201;
217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static const unsigned char kObjectMetaDataTypeMaximum = 255;
219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static const unsigned char kIndexMetaDataTypeMaximum = 255;
220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const unsigned char kMinimumIndexId = 30;
222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochinline void EncodeIntSafely(int64 nParam, int64 max, std::string* into) {
224868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK_LE(nParam, max);
225868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return EncodeInt(nParam, into);
226868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
227868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstd::string MaxIDBKey() {
2297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::string ret;
230868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EncodeByte(kIndexedDBKeyNullTypeByte, &ret);
231868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return ret;
232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
233868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstd::string MinIDBKey() {
2357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::string ret;
236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EncodeByte(kIndexedDBKeyMinKeyTypeByte, &ret);
237868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return ret;
238868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
239868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid EncodeByte(unsigned char value, std::string* into) {
241868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  into->push_back(value);
242868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
243868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid EncodeBool(bool value, std::string* into) {
245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  into->push_back(value ? 1 : 0);
246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid EncodeInt(int64 value, std::string* into) {
249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#ifndef NDEBUG
250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Exercised by unit tests in debug only.
251868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK_GE(value, 0);
252868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif
253868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  uint64 n = static_cast<uint64>(value);
254868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  do {
256868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    unsigned char c = n;
257868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    into->push_back(c);
258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    n >>= 8;
259868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  } while (n);
260868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
261868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid EncodeVarInt(int64 value, std::string* into) {
263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#ifndef NDEBUG
264868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Exercised by unit tests in debug only.
265868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK_GE(value, 0);
266868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif
267868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  uint64 n = static_cast<uint64>(value);
268868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
269868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  do {
270868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    unsigned char c = n & 0x7f;
271868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    n >>= 7;
272868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (n)
273868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      c |= 0x80;
274868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    into->push_back(c);
275868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  } while (n);
276868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
277868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
278a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void EncodeString(const base::string16& value, std::string* into) {
279868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (value.empty())
280868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
281868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Backing store is UTF-16BE, convert from host endianness.
282868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  size_t length = value.length();
283868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  size_t current = into->size();
2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  into->resize(into->size() + length * sizeof(base::char16));
285868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::char16* src = value.c_str();
2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::char16* dst =
2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      reinterpret_cast<base::char16*>(&*into->begin() + current);
289868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  for (unsigned i = 0; i < length; ++i)
290868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    *dst++ = htons(*src++);
291868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
292868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
293f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void EncodeBinary(const std::string& value, std::string* into) {
294f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EncodeVarInt(value.length(), into);
295f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  into->append(value.begin(), value.end());
296f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(into->size() >= value.size());
297f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
298f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
299a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void EncodeStringWithLength(const base::string16& value, std::string* into) {
300868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EncodeVarInt(value.length(), into);
301868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EncodeString(value, into);
302868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
303868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid EncodeDouble(double value, std::string* into) {
305868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // This always has host endianness.
306868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const char* p = reinterpret_cast<char*>(&value);
307868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  into->insert(into->end(), p, p + sizeof(value));
308868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
309868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid EncodeIDBKey(const IndexedDBKey& value, std::string* into) {
311868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  size_t previous_size = into->size();
312868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(value.IsValid());
313868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  switch (value.type()) {
314ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    case WebIDBKeyTypeArray: {
315868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      EncodeByte(kIndexedDBKeyArrayTypeByte, into);
316868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      size_t length = value.array().size();
317868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      EncodeVarInt(length, into);
318868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      for (size_t i = 0; i < length; ++i)
319868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        EncodeIDBKey(value.array()[i], into);
320868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      DCHECK_GT(into->size(), previous_size);
321868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return;
322868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
32323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    case WebIDBKeyTypeBinary:
324f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EncodeByte(kIndexedDBKeyBinaryTypeByte, into);
325f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EncodeBinary(value.binary(), into);
326f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      DCHECK_GT(into->size(), previous_size);
327f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return;
32823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    case WebIDBKeyTypeString:
329868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      EncodeByte(kIndexedDBKeyStringTypeByte, into);
330868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      EncodeStringWithLength(value.string(), into);
331868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      DCHECK_GT(into->size(), previous_size);
332868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return;
33323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    case WebIDBKeyTypeDate:
334868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      EncodeByte(kIndexedDBKeyDateTypeByte, into);
335868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      EncodeDouble(value.date(), into);
3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      DCHECK_EQ(9u, static_cast<size_t>(into->size() - previous_size));
337868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return;
33823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    case WebIDBKeyTypeNumber:
339868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      EncodeByte(kIndexedDBKeyNumberTypeByte, into);
340868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      EncodeDouble(value.number(), into);
3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      DCHECK_EQ(9u, static_cast<size_t>(into->size() - previous_size));
342868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return;
34323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    case WebIDBKeyTypeNull:
34423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    case WebIDBKeyTypeInvalid:
34523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    case WebIDBKeyTypeMin:
34623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    default:
34723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      NOTREACHED();
34823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      EncodeByte(kIndexedDBKeyNullTypeByte, into);
34923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      return;
350868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
351868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid EncodeIDBKeyPath(const IndexedDBKeyPath& value, std::string* into) {
354868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // May be typed, or may be a raw string. An invalid leading
355868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // byte is used to identify typed coding. New records are
356868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // always written as typed.
357868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EncodeByte(kIndexedDBKeyPathTypeCodedByte1, into);
358868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EncodeByte(kIndexedDBKeyPathTypeCodedByte2, into);
359868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EncodeByte(static_cast<char>(value.type()), into);
360868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  switch (value.type()) {
361ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    case WebIDBKeyPathTypeNull:
362868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      break;
363ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    case WebIDBKeyPathTypeString: {
364868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      EncodeStringWithLength(value.string(), into);
365868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      break;
366868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
367ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    case WebIDBKeyPathTypeArray: {
368a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const std::vector<base::string16>& array = value.array();
369868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      size_t count = array.size();
370868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      EncodeVarInt(count, into);
371868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      for (size_t i = 0; i < count; ++i) {
372868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        EncodeStringWithLength(array[i], into);
373868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      }
374868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      break;
375868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
376868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
377868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
378868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
379010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void EncodeBlobJournal(const BlobJournalType& journal, std::string* into) {
380010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  BlobJournalType::const_iterator iter;
381010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  for (iter = journal.begin(); iter != journal.end(); ++iter) {
382010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    EncodeVarInt(iter->first, into);
383010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    EncodeVarInt(iter->second, into);
384010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
385010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
386010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
387868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool DecodeByte(StringPiece* slice, unsigned char* value) {
388868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (slice->empty())
389868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return false;
390868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
391868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  *value = (*slice)[0];
392868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  slice->remove_prefix(1);
393868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return true;
394868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
395868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
396868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool DecodeBool(StringPiece* slice, bool* value) {
397868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (slice->empty())
398868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return false;
399868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
400868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  *value = !!(*slice)[0];
401868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  slice->remove_prefix(1);
402868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return true;
403868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
404868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
405868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool DecodeInt(StringPiece* slice, int64* value) {
406868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (slice->empty())
407868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return false;
408868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
409868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  StringPiece::const_iterator it = slice->begin();
410868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int shift = 0;
411868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int64 ret = 0;
412868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  while (it != slice->end()) {
413868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    unsigned char c = *it++;
414868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ret |= static_cast<int64>(c) << shift;
415868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    shift += 8;
416868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
417868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  *value = ret;
418868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  slice->remove_prefix(it - slice->begin());
419868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return true;
420868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
421868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
422868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool DecodeVarInt(StringPiece* slice, int64* value) {
423868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (slice->empty())
424868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return false;
425868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
426868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  StringPiece::const_iterator it = slice->begin();
427868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int shift = 0;
428868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int64 ret = 0;
429868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  do {
430868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (it == slice->end())
431868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return false;
432868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
433868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    unsigned char c = *it;
434868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ret |= static_cast<int64>(c & 0x7f) << shift;
435868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    shift += 7;
436868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  } while (*it++ & 0x80);
437868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  *value = ret;
438868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  slice->remove_prefix(it - slice->begin());
439868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return true;
440868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
441868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
442a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool DecodeString(StringPiece* slice, base::string16* value) {
443868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (slice->empty()) {
444868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    value->clear();
445868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return true;
446868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
447868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
448868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Backing store is UTF-16BE, convert to host endianness.
4495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!(slice->size() % sizeof(base::char16)));
4505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  size_t length = slice->size() / sizeof(base::char16);
451a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 decoded;
452868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  decoded.reserve(length);
4535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::char16* encoded =
4545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      reinterpret_cast<const base::char16*>(slice->begin());
455868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  for (unsigned i = 0; i < length; ++i)
456868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    decoded.push_back(ntohs(*encoded++));
457868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
458868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  *value = decoded;
4595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  slice->remove_prefix(length * sizeof(base::char16));
460868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return true;
461868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
462868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
463a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool DecodeStringWithLength(StringPiece* slice, base::string16* value) {
464868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (slice->empty())
465868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return false;
466868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
467868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int64 length = 0;
468868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!DecodeVarInt(slice, &length) || length < 0)
469868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return false;
4705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  size_t bytes = length * sizeof(base::char16);
471868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (slice->size() < bytes)
472868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return false;
473868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
474868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  StringPiece subpiece(slice->begin(), bytes);
475868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  slice->remove_prefix(bytes);
476868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!DecodeString(&subpiece, value))
477868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return false;
478868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
479868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return true;
480868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
481868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
482f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool DecodeBinary(StringPiece* slice, std::string* value) {
483f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (slice->empty())
484f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return false;
485f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
486f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int64 length = 0;
487f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!DecodeVarInt(slice, &length) || length < 0)
488f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return false;
489f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  size_t size = length;
490f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (slice->size() < size)
491f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return false;
492f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
493f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  value->assign(slice->begin(), size);
494f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  slice->remove_prefix(size);
495f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return true;
496f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
497f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
498868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool DecodeIDBKey(StringPiece* slice, scoped_ptr<IndexedDBKey>* value) {
499868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (slice->empty())
500868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return false;
501868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
502868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  unsigned char type = (*slice)[0];
503868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  slice->remove_prefix(1);
504868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
505868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  switch (type) {
506868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case kIndexedDBKeyNullTypeByte:
507868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      *value = make_scoped_ptr(new IndexedDBKey());
508868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return true;
509868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
510868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case kIndexedDBKeyArrayTypeByte: {
511868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      int64 length = 0;
512868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      if (!DecodeVarInt(slice, &length) || length < 0)
513868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        return false;
514868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      IndexedDBKey::KeyArray array;
515868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      while (length--) {
516868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        scoped_ptr<IndexedDBKey> key;
517868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        if (!DecodeIDBKey(slice, &key))
518868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          return false;
519868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        array.push_back(*key);
520868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      }
521868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      *value = make_scoped_ptr(new IndexedDBKey(array));
522868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return true;
523868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
524f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case kIndexedDBKeyBinaryTypeByte: {
525f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      std::string binary;
526f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      if (!DecodeBinary(slice, &binary))
527f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        return false;
528f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      *value = make_scoped_ptr(new IndexedDBKey(binary));
529f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return true;
530f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
531868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case kIndexedDBKeyStringTypeByte: {
532a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      base::string16 s;
533868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      if (!DecodeStringWithLength(slice, &s))
534868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        return false;
535868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      *value = make_scoped_ptr(new IndexedDBKey(s));
536868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return true;
537868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
538868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case kIndexedDBKeyDateTypeByte: {
539868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      double d;
540868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      if (!DecodeDouble(slice, &d))
541868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        return false;
542ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      *value = make_scoped_ptr(new IndexedDBKey(d, WebIDBKeyTypeDate));
543868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return true;
544868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
545868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case kIndexedDBKeyNumberTypeByte: {
546868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      double d;
547868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      if (!DecodeDouble(slice, &d))
548868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        return false;
549ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      *value = make_scoped_ptr(new IndexedDBKey(d, WebIDBKeyTypeNumber));
550868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return true;
551868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
552868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
553868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
554868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NOTREACHED();
555868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return false;
556868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
557868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
558868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool DecodeDouble(StringPiece* slice, double* value) {
559868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (slice->size() < sizeof(*value))
560868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return false;
561868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
562868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  memcpy(value, slice->begin(), sizeof(*value));
563868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  slice->remove_prefix(sizeof(*value));
564868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return true;
565868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
566868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
567868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool DecodeIDBKeyPath(StringPiece* slice, IndexedDBKeyPath* value) {
568868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // May be typed, or may be a raw string. An invalid leading
569868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // byte sequence is used to identify typed coding. New records are
570868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // always written as typed.
571868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (slice->size() < 3 || (*slice)[0] != kIndexedDBKeyPathTypeCodedByte1 ||
572868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      (*slice)[1] != kIndexedDBKeyPathTypeCodedByte2) {
573a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    base::string16 s;
574868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (!DecodeString(slice, &s))
575868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return false;
576868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    *value = IndexedDBKeyPath(s);
577868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return true;
578868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
579868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
580868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  slice->remove_prefix(2);
581868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(!slice->empty());
582ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  WebIDBKeyPathType type = static_cast<WebIDBKeyPathType>((*slice)[0]);
583868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  slice->remove_prefix(1);
584868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
585868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  switch (type) {
586ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    case WebIDBKeyPathTypeNull:
587868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      DCHECK(slice->empty());
588868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      *value = IndexedDBKeyPath();
589868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return true;
590ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    case WebIDBKeyPathTypeString: {
591a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      base::string16 string;
592868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      if (!DecodeStringWithLength(slice, &string))
593868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        return false;
594868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      DCHECK(slice->empty());
595868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      *value = IndexedDBKeyPath(string);
596868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return true;
597868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
598ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    case WebIDBKeyPathTypeArray: {
599a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      std::vector<base::string16> array;
600868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      int64 count;
601868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      if (!DecodeVarInt(slice, &count))
602868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        return false;
603868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      DCHECK_GE(count, 0);
604868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      while (count--) {
605a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        base::string16 string;
606868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        if (!DecodeStringWithLength(slice, &string))
607868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          return false;
608868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        array.push_back(string);
609868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      }
610868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      DCHECK(slice->empty());
611868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      *value = IndexedDBKeyPath(array);
612868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return true;
613868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
614868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
615868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NOTREACHED();
616868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return false;
617868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
618868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
619010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool DecodeBlobJournal(StringPiece* slice, BlobJournalType* journal) {
620010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  BlobJournalType output;
621010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  while (!slice->empty()) {
622010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    int64 database_id = -1;
623010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    int64 blob_key = -1;
624010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    if (!DecodeVarInt(slice, &database_id))
625010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      return false;
626010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    if (!KeyPrefix::IsValidDatabaseId(database_id))
627010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      return false;
628010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    if (!DecodeVarInt(slice, &blob_key))
629010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      return false;
630010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    if (!DatabaseMetaDataKey::IsValidBlobKey(blob_key) &&
631010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        (blob_key != DatabaseMetaDataKey::kAllBlobsKey)) {
632010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      return false;
633010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    }
634010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    output.push_back(std::make_pair(database_id, blob_key));
635010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
636010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  journal->swap(output);
637010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return true;
638010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
639010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
640ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbool ConsumeEncodedIDBKey(StringPiece* slice) {
641868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  unsigned char type = (*slice)[0];
642868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  slice->remove_prefix(1);
643868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
644868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  switch (type) {
645868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case kIndexedDBKeyNullTypeByte:
646868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case kIndexedDBKeyMinKeyTypeByte:
647868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return true;
648868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case kIndexedDBKeyArrayTypeByte: {
649868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      int64 length;
650868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      if (!DecodeVarInt(slice, &length))
651868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        return false;
652868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      while (length--) {
653ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        if (!ConsumeEncodedIDBKey(slice))
654868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          return false;
655868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      }
656868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return true;
657868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
658f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case kIndexedDBKeyBinaryTypeByte: {
659f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      int64 length = 0;
660f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      if (!DecodeVarInt(slice, &length) || length < 0)
661f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        return false;
662f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      if (slice->size() < static_cast<size_t>(length))
663f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        return false;
664f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      slice->remove_prefix(length);
665f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return true;
666f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
667868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case kIndexedDBKeyStringTypeByte: {
668868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      int64 length = 0;
669868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      if (!DecodeVarInt(slice, &length) || length < 0)
670868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        return false;
6715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (slice->size() < static_cast<size_t>(length) * sizeof(base::char16))
672868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        return false;
6735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      slice->remove_prefix(length * sizeof(base::char16));
674868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return true;
675868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
676868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case kIndexedDBKeyDateTypeByte:
677868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case kIndexedDBKeyNumberTypeByte:
678868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      if (slice->size() < sizeof(double))
679868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        return false;
680868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      slice->remove_prefix(sizeof(double));
681868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return true;
682868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
683868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NOTREACHED();
684868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return false;
685868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
686868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
6877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool ExtractEncodedIDBKey(StringPiece* slice, std::string* result) {
688868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const char* start = slice->begin();
689ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!ConsumeEncodedIDBKey(slice))
690ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
691868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
692868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (result)
693868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    result->assign(start, slice->begin());
694868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return true;
695868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
696868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
697ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochstatic WebIDBKeyType KeyTypeByteToKeyType(unsigned char type) {
698868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  switch (type) {
699868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case kIndexedDBKeyNullTypeByte:
700ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      return WebIDBKeyTypeInvalid;
701868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case kIndexedDBKeyArrayTypeByte:
702ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      return WebIDBKeyTypeArray;
703f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case kIndexedDBKeyBinaryTypeByte:
704f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return WebIDBKeyTypeBinary;
705868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case kIndexedDBKeyStringTypeByte:
706ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      return WebIDBKeyTypeString;
707868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case kIndexedDBKeyDateTypeByte:
708ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      return WebIDBKeyTypeDate;
709868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case kIndexedDBKeyNumberTypeByte:
710ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      return WebIDBKeyTypeNumber;
711868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case kIndexedDBKeyMinKeyTypeByte:
712ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      return WebIDBKeyTypeMin;
713868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
714868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
715868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NOTREACHED();
716ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return WebIDBKeyTypeInvalid;
717868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
718868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
719868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int CompareEncodedStringsWithLength(StringPiece* slice1,
720868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                    StringPiece* slice2,
721868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                    bool* ok) {
722868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int64 len1, len2;
723868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!DecodeVarInt(slice1, &len1) || !DecodeVarInt(slice2, &len2)) {
724868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    *ok = false;
725868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return 0;
726868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
727868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK_GE(len1, 0);
728868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK_GE(len2, 0);
729868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (len1 < 0 || len2 < 0) {
730868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    *ok = false;
731868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return 0;
732868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
7335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK_GE(slice1->size(), len1 * sizeof(base::char16));
7345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK_GE(slice2->size(), len2 * sizeof(base::char16));
7355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (slice1->size() < len1 * sizeof(base::char16) ||
7365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      slice2->size() < len2 * sizeof(base::char16)) {
737868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    *ok = false;
738868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return 0;
739868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
740868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
741f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Extract the string data, and advance the passed slices.
7425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  StringPiece string1(slice1->begin(), len1 * sizeof(base::char16));
7435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  StringPiece string2(slice2->begin(), len2 * sizeof(base::char16));
7445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  slice1->remove_prefix(len1 * sizeof(base::char16));
7455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  slice2->remove_prefix(len2 * sizeof(base::char16));
746868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
747868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  *ok = true;
748868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Strings are UTF-16BE encoded, so a simple memcmp is sufficient.
749868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return string1.compare(string2);
750868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
751868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
752f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)int CompareEncodedBinary(StringPiece* slice1,
753f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                         StringPiece* slice2,
754f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                         bool* ok) {
755f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int64 len1, len2;
756f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!DecodeVarInt(slice1, &len1) || !DecodeVarInt(slice2, &len2)) {
757f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    *ok = false;
758f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return 0;
759f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
760f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(len1, 0);
761f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(len2, 0);
762f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (len1 < 0 || len2 < 0) {
763f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    *ok = false;
764f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return 0;
765f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
766f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  size_t size1 = len1;
767f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  size_t size2 = len2;
768f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
769f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(slice1->size(), size1);
770f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_GE(slice2->size(), size2);
771f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (slice1->size() < size1 || slice2->size() < size2) {
772f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    *ok = false;
773f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return 0;
774f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
775f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
776f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Extract the binary data, and advance the passed slices.
777f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  StringPiece binary1(slice1->begin(), size1);
778f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  StringPiece binary2(slice2->begin(), size2);
779f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  slice1->remove_prefix(size1);
780f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  slice2->remove_prefix(size2);
781f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
782f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  *ok = true;
783f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // This is the same as a memcmp()
784f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return binary1.compare(binary2);
785f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
786f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
787868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static int CompareInts(int64 a, int64 b) {
788868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#ifndef NDEBUG
789868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Exercised by unit tests in debug only.
790868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK_GE(a, 0);
791868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK_GE(b, 0);
792868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif
793868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int64 diff = a - b;
794868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (diff < 0)
795868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return -1;
796868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (diff > 0)
797868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return 1;
798868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return 0;
799868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
800868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
80158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)static inline int CompareSizes(size_t a, size_t b) {
80258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (a > b)
80358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return 1;
80458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (b > a)
80558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return -1;
80658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return 0;
80758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
80858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
809ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochstatic int CompareTypes(WebIDBKeyType a, WebIDBKeyType b) { return b - a; }
810868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
811868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int CompareEncodedIDBKeys(StringPiece* slice_a,
812868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                          StringPiece* slice_b,
813868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                          bool* ok) {
81458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(!slice_a->empty());
81558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(!slice_b->empty());
816868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  *ok = true;
817868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  unsigned char type_a = (*slice_a)[0];
818868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  unsigned char type_b = (*slice_b)[0];
819868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  slice_a->remove_prefix(1);
820868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  slice_b->remove_prefix(1);
821868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
822868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (int x = CompareTypes(KeyTypeByteToKeyType(type_a),
823868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           KeyTypeByteToKeyType(type_b)))
824868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return x;
825868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
826868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  switch (type_a) {
827868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case kIndexedDBKeyNullTypeByte:
828868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case kIndexedDBKeyMinKeyTypeByte:
829868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // Null type or max type; no payload to compare.
830868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return 0;
831868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case kIndexedDBKeyArrayTypeByte: {
832868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      int64 length_a, length_b;
833868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      if (!DecodeVarInt(slice_a, &length_a) ||
834868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          !DecodeVarInt(slice_b, &length_b)) {
835868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        *ok = false;
836868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        return 0;
837868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      }
838868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      for (int64 i = 0; i < length_a && i < length_b; ++i) {
839868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        int result = CompareEncodedIDBKeys(slice_a, slice_b, ok);
840868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        if (!*ok || result)
841868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          return result;
842868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      }
843868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return length_a - length_b;
844868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
845f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case kIndexedDBKeyBinaryTypeByte:
846f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return CompareEncodedBinary(slice_a, slice_b, ok);
847868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case kIndexedDBKeyStringTypeByte:
848868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return CompareEncodedStringsWithLength(slice_a, slice_b, ok);
849868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case kIndexedDBKeyDateTypeByte:
850868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case kIndexedDBKeyNumberTypeByte: {
851868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      double d, e;
852868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      if (!DecodeDouble(slice_a, &d) || !DecodeDouble(slice_b, &e)) {
853868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        *ok = false;
854868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        return 0;
855868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      }
856868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      if (d < e)
857868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        return -1;
858868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      if (d > e)
859868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        return 1;
860868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return 0;
861868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
862868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
863868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
864868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NOTREACHED();
865868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return 0;
866868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
867868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
868868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace {
869868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
870868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)template <typename KeyType>
8713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)int Compare(const StringPiece& a,
8723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            const StringPiece& b,
8733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            bool only_compare_index_keys,
8743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            bool* ok) {
875868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  KeyType key_a;
876868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  KeyType key_b;
877868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
878ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  StringPiece slice_a(a);
879ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!KeyType::Decode(&slice_a, &key_a)) {
880868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    *ok = false;
881868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return 0;
882868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
883ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  StringPiece slice_b(b);
884ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!KeyType::Decode(&slice_b, &key_b)) {
885868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    *ok = false;
886868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return 0;
887868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
888868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
889868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  *ok = true;
890868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return key_a.Compare(key_b);
891868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
892868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
89358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)template <typename KeyType>
89458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)int CompareSuffix(StringPiece* a,
89558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  StringPiece* b,
89658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  bool only_compare_index_keys,
89758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  bool* ok) {
89858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  NOTREACHED();
89958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return 0;
90058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
90158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
90258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)template <>
90358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)int CompareSuffix<ExistsEntryKey>(StringPiece* slice_a,
90458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                  StringPiece* slice_b,
90558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                  bool only_compare_index_keys,
90658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                  bool* ok) {
90758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(!slice_a->empty());
90858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(!slice_b->empty());
90958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return CompareEncodedIDBKeys(slice_a, slice_b, ok);
91058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
91158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
912868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)template <>
91358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)int CompareSuffix<ObjectStoreDataKey>(StringPiece* slice_a,
91458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                      StringPiece* slice_b,
91558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                      bool only_compare_index_keys,
91658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                      bool* ok) {
91758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return CompareEncodedIDBKeys(slice_a, slice_b, ok);
918868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
919868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
920868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)template <>
921a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)int CompareSuffix<BlobEntryKey>(StringPiece* slice_a,
922a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                StringPiece* slice_b,
923a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                bool only_compare_index_keys,
924a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                bool* ok) {
925a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return CompareEncodedIDBKeys(slice_a, slice_b, ok);
926a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
927a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
928a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)template <>
92958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)int CompareSuffix<IndexDataKey>(StringPiece* slice_a,
93058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                StringPiece* slice_b,
93158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                bool only_compare_index_keys,
93258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                bool* ok) {
93358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // index key
93458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  int result = CompareEncodedIDBKeys(slice_a, slice_b, ok);
93558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!*ok || result)
93658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return result;
93758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (only_compare_index_keys)
93858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return 0;
93958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
94058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // sequence number [optional]
94158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  int64 sequence_number_a = -1;
94258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  int64 sequence_number_b = -1;
94358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!slice_a->empty() && !DecodeVarInt(slice_a, &sequence_number_a))
94458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      return 0;
94558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!slice_b->empty() && !DecodeVarInt(slice_b, &sequence_number_b))
94658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      return 0;
94758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
94858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (slice_a->empty() || slice_b->empty())
94958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return CompareSizes(slice_a->size(), slice_b->size());
95058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
95158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // primary key [optional]
95258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  result = CompareEncodedIDBKeys(slice_a, slice_b, ok);
95358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!*ok || result)
95458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return result;
95558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
95658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return CompareInts(sequence_number_a, sequence_number_b);
957868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
958868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
9597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochint Compare(const StringPiece& a,
9607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            const StringPiece& b,
9613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            bool only_compare_index_keys,
962868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            bool* ok) {
963ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  StringPiece slice_a(a);
964ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  StringPiece slice_b(b);
965868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  KeyPrefix prefix_a;
966868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  KeyPrefix prefix_b;
967ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  bool ok_a = KeyPrefix::Decode(&slice_a, &prefix_a);
968ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  bool ok_b = KeyPrefix::Decode(&slice_b, &prefix_b);
969ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  DCHECK(ok_a);
970ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  DCHECK(ok_b);
971ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!ok_a || !ok_b) {
972868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    *ok = false;
973868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return 0;
974868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
975868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
976868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  *ok = true;
977868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (int x = prefix_a.Compare(prefix_b))
978868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return x;
979868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
9807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  switch (prefix_a.type()) {
9817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case KeyPrefix::GLOBAL_METADATA: {
982ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      DCHECK(!slice_a.empty());
983ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      DCHECK(!slice_b.empty());
984ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
985ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      unsigned char type_byte_a;
986ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      if (!DecodeByte(&slice_a, &type_byte_a)) {
987ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        *ok = false;
988ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        return 0;
989ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      }
990868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
991ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      unsigned char type_byte_b;
992ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      if (!DecodeByte(&slice_b, &type_byte_b)) {
993ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        *ok = false;
994ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        return 0;
995ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      }
996868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
9977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if (int x = type_byte_a - type_byte_b)
9987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        return x;
9997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if (type_byte_a < kMaxSimpleGlobalMetaDataTypeByte)
10007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        return 0;
1001868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
100258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      // Compare<> is used (which re-decodes the prefix) rather than an
100358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      // specialized CompareSuffix<> because metadata is relatively uncommon
100458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      // in the database.
100558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
10065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (type_byte_a == kDatabaseFreeListTypeByte) {
10075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        // TODO(jsbell): No need to pass only_compare_index_keys through here.
10085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        return Compare<DatabaseFreeListKey>(a, b, only_compare_index_keys, ok);
10095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      }
10105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (type_byte_a == kDatabaseNameTypeByte) {
10113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        return Compare<DatabaseNameKey>(
10123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            a, b, /*only_compare_index_keys*/ false, ok);
10135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      }
10147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      break;
10157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
1016868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
10177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case KeyPrefix::DATABASE_METADATA: {
1018ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      DCHECK(!slice_a.empty());
1019ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      DCHECK(!slice_b.empty());
1020868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1021ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      unsigned char type_byte_a;
1022ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      if (!DecodeByte(&slice_a, &type_byte_a)) {
1023ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        *ok = false;
1024ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        return 0;
1025ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      }
1026ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
1027ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      unsigned char type_byte_b;
1028ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      if (!DecodeByte(&slice_b, &type_byte_b)) {
1029ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        *ok = false;
1030ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        return 0;
1031ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      }
1032868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
10337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if (int x = type_byte_a - type_byte_b)
10347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        return x;
10357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if (type_byte_a < DatabaseMetaDataKey::MAX_SIMPLE_METADATA_TYPE)
10367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        return 0;
1037868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
103858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      // Compare<> is used (which re-decodes the prefix) rather than an
103958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      // specialized CompareSuffix<> because metadata is relatively uncommon
104058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      // in the database.
104158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
10425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (type_byte_a == kObjectStoreMetaDataTypeByte) {
10435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        // TODO(jsbell): No need to pass only_compare_index_keys through here.
10443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        return Compare<ObjectStoreMetaDataKey>(
10453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            a, b, only_compare_index_keys, ok);
10465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      }
10475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (type_byte_a == kIndexMetaDataTypeByte) {
10483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        return Compare<IndexMetaDataKey>(
10493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            a, b, /*only_compare_index_keys*/ false, ok);
10505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      }
10515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (type_byte_a == kObjectStoreFreeListTypeByte) {
10523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        return Compare<ObjectStoreFreeListKey>(
10533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            a, b, only_compare_index_keys, ok);
10545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      }
10555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (type_byte_a == kIndexFreeListTypeByte) {
10563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        return Compare<IndexFreeListKey>(
10573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            a, b, /*only_compare_index_keys*/ false, ok);
10585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      }
10595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (type_byte_a == kObjectStoreNamesTypeByte) {
10605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        // TODO(jsbell): No need to pass only_compare_index_keys through here.
10613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        return Compare<ObjectStoreNamesKey>(
10623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            a, b, only_compare_index_keys, ok);
10635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      }
10645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (type_byte_a == kIndexNamesKeyTypeByte) {
10653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        return Compare<IndexNamesKey>(
10663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            a, b, /*only_compare_index_keys*/ false, ok);
10675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      }
10687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      break;
10697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
1070868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
10717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case KeyPrefix::OBJECT_STORE_DATA: {
107258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      // Provide a stable ordering for invalid data.
1073ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      if (slice_a.empty() || slice_b.empty())
107458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        return CompareSizes(slice_a.size(), slice_b.size());
1075868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
107658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      return CompareSuffix<ObjectStoreDataKey>(
107758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          &slice_a, &slice_b, /*only_compare_index_keys*/ false, ok);
10787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
1079868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
10807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case KeyPrefix::EXISTS_ENTRY: {
108158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      // Provide a stable ordering for invalid data.
1082ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      if (slice_a.empty() || slice_b.empty())
108358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        return CompareSizes(slice_a.size(), slice_b.size());
10847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
108558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      return CompareSuffix<ExistsEntryKey>(
108658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          &slice_a, &slice_b, /*only_compare_index_keys*/ false, ok);
10877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
10887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1089a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    case KeyPrefix::BLOB_ENTRY: {
1090a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // Provide a stable ordering for invalid data.
1091a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      if (slice_a.empty() || slice_b.empty())
1092a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        return CompareSizes(slice_a.size(), slice_b.size());
1093a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1094a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return CompareSuffix<BlobEntryKey>(
1095a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          &slice_a, &slice_b, /*only_compare_index_keys*/ false, ok);
1096a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
1097a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
10987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case KeyPrefix::INDEX_DATA: {
109958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      // Provide a stable ordering for invalid data.
1100ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      if (slice_a.empty() || slice_b.empty())
110158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        return CompareSizes(slice_a.size(), slice_b.size());
11027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
110358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      return CompareSuffix<IndexDataKey>(
110458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          &slice_a, &slice_b, only_compare_index_keys, ok);
11057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
11067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
11077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case KeyPrefix::INVALID_TYPE:
11087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      break;
1109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
1110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NOTREACHED();
1112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  *ok = false;
1113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return 0;
1114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}  // namespace
1117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
11183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)int Compare(const StringPiece& a,
11193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            const StringPiece& b,
11203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            bool only_compare_index_keys) {
1121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  bool ok;
11223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  int result = Compare(a, b, only_compare_index_keys, &ok);
1123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(ok);
1124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!ok)
1125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return 0;
1126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return result;
1127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)KeyPrefix::KeyPrefix()
1130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    : database_id_(INVALID_TYPE),
1131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      object_store_id_(INVALID_TYPE),
1132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      index_id_(INVALID_TYPE) {}
1133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)KeyPrefix::KeyPrefix(int64 database_id)
1135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    : database_id_(database_id), object_store_id_(0), index_id_(0) {
1136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
1137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)KeyPrefix::KeyPrefix(int64 database_id, int64 object_store_id)
1140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    : database_id_(database_id),
1141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      object_store_id_(object_store_id),
1142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      index_id_(0) {
1143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
1144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(KeyPrefix::IsValidObjectStoreId(object_store_id));
1145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)KeyPrefix::KeyPrefix(int64 database_id, int64 object_store_id, int64 index_id)
1148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    : database_id_(database_id),
1149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      object_store_id_(object_store_id),
1150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      index_id_(index_id) {
1151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
1152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(KeyPrefix::IsValidObjectStoreId(object_store_id));
1153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(KeyPrefix::IsValidIndexId(index_id));
1154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)KeyPrefix::KeyPrefix(enum Type type,
1157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                     int64 database_id,
1158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                     int64 object_store_id,
1159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                     int64 index_id)
1160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    : database_id_(database_id),
1161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      object_store_id_(object_store_id),
1162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      index_id_(index_id) {
1163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK_EQ(type, INVALID_TYPE);
1164868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
1165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(KeyPrefix::IsValidObjectStoreId(object_store_id));
1166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)KeyPrefix KeyPrefix::CreateWithSpecialIndex(int64 database_id,
1169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                            int64 object_store_id,
1170868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                            int64 index_id) {
1171868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
1172868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(KeyPrefix::IsValidObjectStoreId(object_store_id));
1173868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(index_id);
1174868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return KeyPrefix(INVALID_TYPE, database_id, object_store_id, index_id);
1175868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool KeyPrefix::IsValidDatabaseId(int64 database_id) {
1178868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return (database_id > 0) && (database_id < KeyPrefix::kMaxDatabaseId);
1179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool KeyPrefix::IsValidObjectStoreId(int64 object_store_id) {
1182868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return (object_store_id > 0) &&
1183868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)         (object_store_id < KeyPrefix::kMaxObjectStoreId);
1184868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1185868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1186868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool KeyPrefix::IsValidIndexId(int64 index_id) {
1187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return (index_id >= kMinimumIndexId) && (index_id < KeyPrefix::kMaxIndexId);
1188868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1189868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1190ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbool KeyPrefix::Decode(StringPiece* slice, KeyPrefix* result) {
1191ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  unsigned char first_byte;
1192ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!DecodeByte(slice, &first_byte))
1193ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
1194868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1195ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  size_t database_id_bytes = ((first_byte >> 5) & 0x7) + 1;
1196ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  size_t object_store_id_bytes = ((first_byte >> 2) & 0x7) + 1;
1197ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  size_t index_id_bytes = (first_byte & 0x3) + 1;
1198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1199ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (database_id_bytes + object_store_id_bytes + index_id_bytes >
1200ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      slice->size())
1201ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
1202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1203868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  {
1204ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    StringPiece tmp(slice->begin(), database_id_bytes);
1205ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    if (!DecodeInt(&tmp, &result->database_id_))
1206ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      return false;
1207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
1208ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  slice->remove_prefix(database_id_bytes);
1209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  {
1210ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    StringPiece tmp(slice->begin(), object_store_id_bytes);
1211ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    if (!DecodeInt(&tmp, &result->object_store_id_))
1212ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      return false;
1213868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
1214ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  slice->remove_prefix(object_store_id_bytes);
1215868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  {
1216ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    StringPiece tmp(slice->begin(), index_id_bytes);
1217ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    if (!DecodeInt(&tmp, &result->index_id_))
1218ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      return false;
1219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
1220ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  slice->remove_prefix(index_id_bytes);
1221ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return true;
1222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1223868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
12247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstd::string KeyPrefix::EncodeEmpty() {
12257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  const std::string result(4, 0);
12267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(EncodeInternal(0, 0, 0) == std::string(4, 0));
1227868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return result;
1228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
12307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstd::string KeyPrefix::Encode() const {
1231868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(database_id_ != kInvalidId);
1232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(object_store_id_ != kInvalidId);
1233868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(index_id_ != kInvalidId);
1234868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return EncodeInternal(database_id_, object_store_id_, index_id_);
1235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
12377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstd::string KeyPrefix::EncodeInternal(int64 database_id,
12387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                      int64 object_store_id,
12397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                      int64 index_id) {
12407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::string database_id_string;
12417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::string object_store_id_string;
12427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::string index_id_string;
1243868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1244868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EncodeIntSafely(database_id, kMaxDatabaseId, &database_id_string);
1245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EncodeIntSafely(object_store_id, kMaxObjectStoreId, &object_store_id_string);
1246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EncodeIntSafely(index_id, kMaxIndexId, &index_id_string);
1247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(database_id_string.size() <= kMaxDatabaseIdSizeBytes);
1249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(object_store_id_string.size() <= kMaxObjectStoreIdSizeBytes);
1250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(index_id_string.size() <= kMaxIndexIdSizeBytes);
1251868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1252868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  unsigned char first_byte =
1253ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      (database_id_string.size() - 1) << (kMaxObjectStoreIdSizeBits +
1254ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                          kMaxIndexIdSizeBits) |
1255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      (object_store_id_string.size() - 1) << kMaxIndexIdSizeBits |
1256868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      (index_id_string.size() - 1);
1257868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  COMPILE_ASSERT(kMaxDatabaseIdSizeBits + kMaxObjectStoreIdSizeBits +
1258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                         kMaxIndexIdSizeBits ==
1259868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                     sizeof(first_byte) * 8,
1260868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                 CANT_ENCODE_IDS);
12617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::string ret;
1262868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ret.reserve(kDefaultInlineBufferSize);
1263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ret.push_back(first_byte);
12647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ret.append(database_id_string);
12657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ret.append(object_store_id_string);
12667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ret.append(index_id_string);
1267868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1268868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK_LE(ret.size(), kDefaultInlineBufferSize);
1269868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return ret;
1270868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1271868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1272868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int KeyPrefix::Compare(const KeyPrefix& other) const {
1273868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(database_id_ != kInvalidId);
1274868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(object_store_id_ != kInvalidId);
1275868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(index_id_ != kInvalidId);
1276868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1277868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (database_id_ != other.database_id_)
1278868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return CompareInts(database_id_, other.database_id_);
1279868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (object_store_id_ != other.object_store_id_)
1280868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return CompareInts(object_store_id_, other.object_store_id_);
1281868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (index_id_ != other.index_id_)
1282868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return CompareInts(index_id_, other.index_id_);
1283868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return 0;
1284868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1285868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1286868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)KeyPrefix::Type KeyPrefix::type() const {
1287868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(database_id_ != kInvalidId);
1288868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(object_store_id_ != kInvalidId);
1289868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(index_id_ != kInvalidId);
1290868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1291868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!database_id_)
1292868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return GLOBAL_METADATA;
1293868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!object_store_id_)
1294868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return DATABASE_METADATA;
1295868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (index_id_ == kObjectStoreDataIndexId)
1296868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return OBJECT_STORE_DATA;
1297868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (index_id_ == kExistsEntryIndexId)
1298868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return EXISTS_ENTRY;
1299a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (index_id_ == kBlobEntryIndexId)
1300a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return BLOB_ENTRY;
1301868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (index_id_ >= kMinimumIndexId)
1302868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return INDEX_DATA;
1303868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1304868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NOTREACHED();
1305868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return INVALID_TYPE;
1306868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1307868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
13087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstd::string SchemaVersionKey::Encode() {
13097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::string ret = KeyPrefix::EncodeEmpty();
1310868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ret.push_back(kSchemaVersionTypeByte);
1311868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return ret;
1312868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1313868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
13147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstd::string MaxDatabaseIdKey::Encode() {
13157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::string ret = KeyPrefix::EncodeEmpty();
1316868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ret.push_back(kMaxDatabaseIdTypeByte);
1317868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return ret;
1318868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1319868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
13207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstd::string DataVersionKey::Encode() {
13217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::string ret = KeyPrefix::EncodeEmpty();
1322868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ret.push_back(kDataVersionTypeByte);
1323868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return ret;
1324868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1325868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1326a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)std::string BlobJournalKey::Encode() {
1327a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::string ret = KeyPrefix::EncodeEmpty();
1328a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ret.push_back(kBlobJournalTypeByte);
1329a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return ret;
1330a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
1331a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1332a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)std::string LiveBlobJournalKey::Encode() {
1333a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::string ret = KeyPrefix::EncodeEmpty();
1334a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ret.push_back(kLiveBlobJournalTypeByte);
1335a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return ret;
1336a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
1337a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1338868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)DatabaseFreeListKey::DatabaseFreeListKey() : database_id_(-1) {}
1339868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1340ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbool DatabaseFreeListKey::Decode(StringPiece* slice,
1341ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                 DatabaseFreeListKey* result) {
1342868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  KeyPrefix prefix;
1343ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!KeyPrefix::Decode(slice, &prefix))
1344ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
1345868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(!prefix.database_id_);
1346868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(!prefix.object_store_id_);
1347868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(!prefix.index_id_);
1348868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  unsigned char type_byte = 0;
1349ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!DecodeByte(slice, &type_byte))
1350ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
1351868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK_EQ(type_byte, kDatabaseFreeListTypeByte);
1352ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!DecodeVarInt(slice, &result->database_id_))
1353ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
1354ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return true;
1355868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1356868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
13577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstd::string DatabaseFreeListKey::Encode(int64 database_id) {
13587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::string ret = KeyPrefix::EncodeEmpty();
1359868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ret.push_back(kDatabaseFreeListTypeByte);
1360868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EncodeVarInt(database_id, &ret);
1361868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return ret;
1362868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1363868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
13647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstd::string DatabaseFreeListKey::EncodeMaxKey() {
1365868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return Encode(std::numeric_limits<int64>::max());
1366868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1367868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1368868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int64 DatabaseFreeListKey::DatabaseId() const {
1369868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK_GE(database_id_, 0);
1370868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return database_id_;
1371868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1372868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1373868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int DatabaseFreeListKey::Compare(const DatabaseFreeListKey& other) const {
1374868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK_GE(database_id_, 0);
1375868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return CompareInts(database_id_, other.database_id_);
1376868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1377868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1378ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbool DatabaseNameKey::Decode(StringPiece* slice, DatabaseNameKey* result) {
1379868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  KeyPrefix prefix;
1380ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!KeyPrefix::Decode(slice, &prefix))
1381ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
1382868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(!prefix.database_id_);
1383868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(!prefix.object_store_id_);
1384868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(!prefix.index_id_);
1385868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  unsigned char type_byte = 0;
1386ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!DecodeByte(slice, &type_byte))
1387ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
1388868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK_EQ(type_byte, kDatabaseNameTypeByte);
1389ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!DecodeStringWithLength(slice, &result->origin_))
1390ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
1391ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!DecodeStringWithLength(slice, &result->database_name_))
1392ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
1393ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return true;
1394868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1395868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
13967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstd::string DatabaseNameKey::Encode(const std::string& origin_identifier,
1397a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                    const base::string16& database_name) {
13987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::string ret = KeyPrefix::EncodeEmpty();
1399868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ret.push_back(kDatabaseNameTypeByte);
1400eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EncodeStringWithLength(base::ASCIIToUTF16(origin_identifier), &ret);
1401868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EncodeStringWithLength(database_name, &ret);
1402868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return ret;
1403868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1404868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
14057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstd::string DatabaseNameKey::EncodeMinKeyForOrigin(
1406eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const std::string& origin_identifier) {
1407a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return Encode(origin_identifier, base::string16());
1408868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1409868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
14107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstd::string DatabaseNameKey::EncodeStopKeyForOrigin(
1411eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const std::string& origin_identifier) {
1412868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // just after origin in collation order
1413eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return EncodeMinKeyForOrigin(origin_identifier + '\x01');
1414868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1415868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1416868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int DatabaseNameKey::Compare(const DatabaseNameKey& other) {
1417868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (int x = origin_.compare(other.origin_))
1418868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return x;
1419868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return database_name_.compare(other.database_name_);
1420868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1421868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1422a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool DatabaseMetaDataKey::IsValidBlobKey(int64 blob_key) {
1423a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return blob_key >= kBlobKeyGeneratorInitialNumber;
1424a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
1425a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
142623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)const int64 DatabaseMetaDataKey::kAllBlobsKey = 1;
142723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)const int64 DatabaseMetaDataKey::kBlobKeyGeneratorInitialNumber = 2;
142823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)const int64 DatabaseMetaDataKey::kInvalidBlobKey = -1;
142923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
14307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstd::string DatabaseMetaDataKey::Encode(int64 database_id,
14317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                        MetaDataType meta_data_type) {
1432868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  KeyPrefix prefix(database_id);
14337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::string ret = prefix.Encode();
1434868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ret.push_back(meta_data_type);
1435868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return ret;
1436868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1437868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1438868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ObjectStoreMetaDataKey::ObjectStoreMetaDataKey()
1439868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    : object_store_id_(-1), meta_data_type_(-1) {}
1440868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1441ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbool ObjectStoreMetaDataKey::Decode(StringPiece* slice,
1442ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                    ObjectStoreMetaDataKey* result) {
1443868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  KeyPrefix prefix;
1444ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!KeyPrefix::Decode(slice, &prefix))
1445ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
1446868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(prefix.database_id_);
1447868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(!prefix.object_store_id_);
1448868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(!prefix.index_id_);
1449868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  unsigned char type_byte = 0;
1450ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!DecodeByte(slice, &type_byte))
1451ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
1452868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK_EQ(type_byte, kObjectStoreMetaDataTypeByte);
1453ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!DecodeVarInt(slice, &result->object_store_id_))
1454ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
1455868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(result->object_store_id_);
1456ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!DecodeByte(slice, &result->meta_data_type_))
1457ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
1458ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return true;
1459868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1460868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
14617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstd::string ObjectStoreMetaDataKey::Encode(int64 database_id,
14627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                           int64 object_store_id,
14637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                           unsigned char meta_data_type) {
1464868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  KeyPrefix prefix(database_id);
14657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::string ret = prefix.Encode();
1466868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ret.push_back(kObjectStoreMetaDataTypeByte);
1467868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EncodeVarInt(object_store_id, &ret);
1468868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ret.push_back(meta_data_type);
1469868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return ret;
1470868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1471868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
14727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstd::string ObjectStoreMetaDataKey::EncodeMaxKey(int64 database_id) {
1473868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return Encode(database_id,
1474868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                std::numeric_limits<int64>::max(),
1475868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                kObjectMetaDataTypeMaximum);
1476868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1477868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
14787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstd::string ObjectStoreMetaDataKey::EncodeMaxKey(int64 database_id,
14797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                                 int64 object_store_id) {
1480868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return Encode(database_id, object_store_id, kObjectMetaDataTypeMaximum);
1481868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1482868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1483868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int64 ObjectStoreMetaDataKey::ObjectStoreId() const {
1484868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK_GE(object_store_id_, 0);
1485868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return object_store_id_;
1486868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1487868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)unsigned char ObjectStoreMetaDataKey::MetaDataType() const {
1488868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return meta_data_type_;
1489868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1490868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1491868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int ObjectStoreMetaDataKey::Compare(const ObjectStoreMetaDataKey& other) {
1492868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK_GE(object_store_id_, 0);
1493868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (int x = CompareInts(object_store_id_, other.object_store_id_))
1494868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return x;
149558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return meta_data_type_ - other.meta_data_type_;
1496868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1497868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1498868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)IndexMetaDataKey::IndexMetaDataKey()
1499868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    : object_store_id_(-1), index_id_(-1), meta_data_type_(0) {}
1500868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1501ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbool IndexMetaDataKey::Decode(StringPiece* slice, IndexMetaDataKey* result) {
1502868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  KeyPrefix prefix;
1503ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!KeyPrefix::Decode(slice, &prefix))
1504ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
1505868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(prefix.database_id_);
1506868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(!prefix.object_store_id_);
1507868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(!prefix.index_id_);
1508868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  unsigned char type_byte = 0;
1509ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!DecodeByte(slice, &type_byte))
1510ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
1511868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK_EQ(type_byte, kIndexMetaDataTypeByte);
1512ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!DecodeVarInt(slice, &result->object_store_id_))
1513ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
1514ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!DecodeVarInt(slice, &result->index_id_))
1515ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
1516ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!DecodeByte(slice, &result->meta_data_type_))
1517ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
1518ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return true;
1519868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1520868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
15217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstd::string IndexMetaDataKey::Encode(int64 database_id,
15227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                     int64 object_store_id,
15237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                     int64 index_id,
15247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                     unsigned char meta_data_type) {
1525868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  KeyPrefix prefix(database_id);
15267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::string ret = prefix.Encode();
1527868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ret.push_back(kIndexMetaDataTypeByte);
1528868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EncodeVarInt(object_store_id, &ret);
1529868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EncodeVarInt(index_id, &ret);
1530868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EncodeByte(meta_data_type, &ret);
1531868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return ret;
1532868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1533868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
15347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstd::string IndexMetaDataKey::EncodeMaxKey(int64 database_id,
15357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                           int64 object_store_id) {
1536868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return Encode(database_id,
1537868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                object_store_id,
1538868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                std::numeric_limits<int64>::max(),
1539868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                kIndexMetaDataTypeMaximum);
1540868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1541868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
15427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstd::string IndexMetaDataKey::EncodeMaxKey(int64 database_id,
15437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                           int64 object_store_id,
15447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                           int64 index_id) {
1545868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return Encode(
1546868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      database_id, object_store_id, index_id, kIndexMetaDataTypeMaximum);
1547868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1548868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1549868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int IndexMetaDataKey::Compare(const IndexMetaDataKey& other) {
1550868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK_GE(object_store_id_, 0);
1551868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK_GE(index_id_, 0);
1552868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1553868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (int x = CompareInts(object_store_id_, other.object_store_id_))
1554868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return x;
1555868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (int x = CompareInts(index_id_, other.index_id_))
1556868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return x;
1557868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return meta_data_type_ - other.meta_data_type_;
1558868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1559868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1560868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int64 IndexMetaDataKey::IndexId() const {
1561868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK_GE(index_id_, 0);
1562868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return index_id_;
1563868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1564868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1565868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ObjectStoreFreeListKey::ObjectStoreFreeListKey() : object_store_id_(-1) {}
1566868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1567ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbool ObjectStoreFreeListKey::Decode(StringPiece* slice,
1568ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                    ObjectStoreFreeListKey* result) {
1569868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  KeyPrefix prefix;
1570ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!KeyPrefix::Decode(slice, &prefix))
1571ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
1572868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(prefix.database_id_);
1573868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(!prefix.object_store_id_);
1574868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(!prefix.index_id_);
1575868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  unsigned char type_byte = 0;
1576ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!DecodeByte(slice, &type_byte))
1577ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
1578868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK_EQ(type_byte, kObjectStoreFreeListTypeByte);
1579ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!DecodeVarInt(slice, &result->object_store_id_))
1580ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
1581ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return true;
1582868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1583868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
15847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstd::string ObjectStoreFreeListKey::Encode(int64 database_id,
15857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                           int64 object_store_id) {
1586868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  KeyPrefix prefix(database_id);
15877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::string ret = prefix.Encode();
1588868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ret.push_back(kObjectStoreFreeListTypeByte);
1589868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EncodeVarInt(object_store_id, &ret);
1590868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return ret;
1591868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1592868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
15937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstd::string ObjectStoreFreeListKey::EncodeMaxKey(int64 database_id) {
1594868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return Encode(database_id, std::numeric_limits<int64>::max());
1595868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1596868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1597868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int64 ObjectStoreFreeListKey::ObjectStoreId() const {
1598868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK_GE(object_store_id_, 0);
1599868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return object_store_id_;
1600868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1601868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1602868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int ObjectStoreFreeListKey::Compare(const ObjectStoreFreeListKey& other) {
1603868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // TODO(jsbell): It may seem strange that we're not comparing database id's,
1604868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // but that comparison will have been made earlier.
1605868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // We should probably make this more clear, though...
1606868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK_GE(object_store_id_, 0);
1607868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return CompareInts(object_store_id_, other.object_store_id_);
1608868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1609868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1610868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)IndexFreeListKey::IndexFreeListKey() : object_store_id_(-1), index_id_(-1) {}
1611868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1612ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbool IndexFreeListKey::Decode(StringPiece* slice, IndexFreeListKey* result) {
1613868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  KeyPrefix prefix;
1614ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!KeyPrefix::Decode(slice, &prefix))
1615ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
1616868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(prefix.database_id_);
1617868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(!prefix.object_store_id_);
1618868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(!prefix.index_id_);
1619868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  unsigned char type_byte = 0;
1620ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!DecodeByte(slice, &type_byte))
1621ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
1622868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK_EQ(type_byte, kIndexFreeListTypeByte);
1623ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!DecodeVarInt(slice, &result->object_store_id_))
1624ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
1625ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!DecodeVarInt(slice, &result->index_id_))
1626ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
1627ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return true;
1628868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1629868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
16307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstd::string IndexFreeListKey::Encode(int64 database_id,
16317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                     int64 object_store_id,
16327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                     int64 index_id) {
1633868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  KeyPrefix prefix(database_id);
16347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::string ret = prefix.Encode();
1635868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ret.push_back(kIndexFreeListTypeByte);
1636868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EncodeVarInt(object_store_id, &ret);
1637868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EncodeVarInt(index_id, &ret);
1638868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return ret;
1639868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1640868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
16417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstd::string IndexFreeListKey::EncodeMaxKey(int64 database_id,
16427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                           int64 object_store_id) {
1643868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return Encode(
1644868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      database_id, object_store_id, std::numeric_limits<int64>::max());
1645868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1646868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1647868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int IndexFreeListKey::Compare(const IndexFreeListKey& other) {
1648868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK_GE(object_store_id_, 0);
1649868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK_GE(index_id_, 0);
1650868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (int x = CompareInts(object_store_id_, other.object_store_id_))
1651868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return x;
1652868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return CompareInts(index_id_, other.index_id_);
1653868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1654868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1655868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int64 IndexFreeListKey::ObjectStoreId() const {
1656868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK_GE(object_store_id_, 0);
1657868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return object_store_id_;
1658868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1659868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1660868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int64 IndexFreeListKey::IndexId() const {
1661868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK_GE(index_id_, 0);
1662868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return index_id_;
1663868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1664868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1665868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// TODO(jsbell): We never use this to look up object store ids,
1666868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// because a mapping is kept in the IndexedDBDatabase. Can the
1667868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// mapping become unreliable?  Can we remove this?
1668ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbool ObjectStoreNamesKey::Decode(StringPiece* slice,
1669ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                 ObjectStoreNamesKey* result) {
1670868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  KeyPrefix prefix;
1671ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!KeyPrefix::Decode(slice, &prefix))
1672ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
1673868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(prefix.database_id_);
1674868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(!prefix.object_store_id_);
1675868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(!prefix.index_id_);
1676868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  unsigned char type_byte = 0;
1677ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!DecodeByte(slice, &type_byte))
1678ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
1679868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK_EQ(type_byte, kObjectStoreNamesTypeByte);
1680ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!DecodeStringWithLength(slice, &result->object_store_name_))
1681ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
1682ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return true;
1683868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1684868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1685a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)std::string ObjectStoreNamesKey::Encode(
1686a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    int64 database_id,
1687a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& object_store_name) {
1688868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  KeyPrefix prefix(database_id);
16897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::string ret = prefix.Encode();
1690868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ret.push_back(kObjectStoreNamesTypeByte);
1691868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EncodeStringWithLength(object_store_name, &ret);
1692868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return ret;
1693868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1694868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1695868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int ObjectStoreNamesKey::Compare(const ObjectStoreNamesKey& other) {
1696868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return object_store_name_.compare(other.object_store_name_);
1697868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1698868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1699868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)IndexNamesKey::IndexNamesKey() : object_store_id_(-1) {}
1700868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1701868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// TODO(jsbell): We never use this to look up index ids, because a mapping
1702868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// is kept at a higher level.
1703ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbool IndexNamesKey::Decode(StringPiece* slice, IndexNamesKey* result) {
1704868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  KeyPrefix prefix;
1705ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!KeyPrefix::Decode(slice, &prefix))
1706ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
1707868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(prefix.database_id_);
1708868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(!prefix.object_store_id_);
1709868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(!prefix.index_id_);
1710868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  unsigned char type_byte = 0;
1711ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!DecodeByte(slice, &type_byte))
1712ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
1713868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK_EQ(type_byte, kIndexNamesKeyTypeByte);
1714ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!DecodeVarInt(slice, &result->object_store_id_))
1715ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
1716ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!DecodeStringWithLength(slice, &result->index_name_))
1717ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
1718ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return true;
1719868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1720868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
17217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstd::string IndexNamesKey::Encode(int64 database_id,
17227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                  int64 object_store_id,
1723a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                  const base::string16& index_name) {
1724868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  KeyPrefix prefix(database_id);
17257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::string ret = prefix.Encode();
1726868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ret.push_back(kIndexNamesKeyTypeByte);
1727868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EncodeVarInt(object_store_id, &ret);
1728868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EncodeStringWithLength(index_name, &ret);
1729868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return ret;
1730868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1731868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1732868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int IndexNamesKey::Compare(const IndexNamesKey& other) {
1733868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK_GE(object_store_id_, 0);
1734868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (int x = CompareInts(object_store_id_, other.object_store_id_))
1735868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return x;
1736868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return index_name_.compare(other.index_name_);
1737868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1738868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1739868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ObjectStoreDataKey::ObjectStoreDataKey() {}
1740868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ObjectStoreDataKey::~ObjectStoreDataKey() {}
1741868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1742ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbool ObjectStoreDataKey::Decode(StringPiece* slice,
1743ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                ObjectStoreDataKey* result) {
1744868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  KeyPrefix prefix;
1745ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!KeyPrefix::Decode(slice, &prefix))
1746ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
1747868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(prefix.database_id_);
1748868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(prefix.object_store_id_);
1749868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK_EQ(prefix.index_id_, kSpecialIndexNumber);
1750ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!ExtractEncodedIDBKey(slice, &result->encoded_user_key_))
1751ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
1752ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return true;
1753868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1754868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
17557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstd::string ObjectStoreDataKey::Encode(int64 database_id,
17567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                       int64 object_store_id,
17577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                       const std::string encoded_user_key) {
1758868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  KeyPrefix prefix(KeyPrefix::CreateWithSpecialIndex(
1759868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      database_id, object_store_id, kSpecialIndexNumber));
17607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::string ret = prefix.Encode();
17617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ret.append(encoded_user_key);
1762868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1763868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return ret;
1764868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1765868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
17667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstd::string ObjectStoreDataKey::Encode(int64 database_id,
17677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                       int64 object_store_id,
17687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                       const IndexedDBKey& user_key) {
17697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::string encoded_key;
1770868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EncodeIDBKey(user_key, &encoded_key);
1771868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return Encode(database_id, object_store_id, encoded_key);
1772868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1773868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1774868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)scoped_ptr<IndexedDBKey> ObjectStoreDataKey::user_key() const {
1775868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<IndexedDBKey> key;
17767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  StringPiece slice(encoded_user_key_);
1777868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!DecodeIDBKey(&slice, &key)) {
1778868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // TODO(jsbell): Return error.
1779868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
1780868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return key.Pass();
1781868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1782868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1783868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const int64 ObjectStoreDataKey::kSpecialIndexNumber = kObjectStoreDataIndexId;
1784868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1785868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ExistsEntryKey::ExistsEntryKey() {}
1786868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ExistsEntryKey::~ExistsEntryKey() {}
1787868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1788ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbool ExistsEntryKey::Decode(StringPiece* slice, ExistsEntryKey* result) {
1789868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  KeyPrefix prefix;
1790ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!KeyPrefix::Decode(slice, &prefix))
1791ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
1792868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(prefix.database_id_);
1793868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(prefix.object_store_id_);
1794868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK_EQ(prefix.index_id_, kSpecialIndexNumber);
1795ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!ExtractEncodedIDBKey(slice, &result->encoded_user_key_))
1796ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
1797ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return true;
1798868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1799868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
18007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstd::string ExistsEntryKey::Encode(int64 database_id,
18017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                   int64 object_store_id,
18027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                   const std::string& encoded_key) {
1803868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  KeyPrefix prefix(KeyPrefix::CreateWithSpecialIndex(
1804868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      database_id, object_store_id, kSpecialIndexNumber));
18057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::string ret = prefix.Encode();
18067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ret.append(encoded_key);
1807868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return ret;
1808868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1809868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
18107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstd::string ExistsEntryKey::Encode(int64 database_id,
18117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                   int64 object_store_id,
18127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                   const IndexedDBKey& user_key) {
18137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::string encoded_key;
1814868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EncodeIDBKey(user_key, &encoded_key);
1815868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return Encode(database_id, object_store_id, encoded_key);
1816868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1817868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1818868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)scoped_ptr<IndexedDBKey> ExistsEntryKey::user_key() const {
1819868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<IndexedDBKey> key;
18207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  StringPiece slice(encoded_user_key_);
1821868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!DecodeIDBKey(&slice, &key)) {
1822868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // TODO(jsbell): Return error.
1823868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
1824868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return key.Pass();
1825868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1826868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1827868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const int64 ExistsEntryKey::kSpecialIndexNumber = kExistsEntryIndexId;
1828868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1829a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool BlobEntryKey::Decode(StringPiece* slice, BlobEntryKey* result) {
1830a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  KeyPrefix prefix;
1831a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!KeyPrefix::Decode(slice, &prefix))
1832a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return false;
1833a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(prefix.database_id_);
1834a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(prefix.object_store_id_);
1835a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK_EQ(prefix.index_id_, kSpecialIndexNumber);
1836a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1837a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!ExtractEncodedIDBKey(slice, &result->encoded_user_key_))
1838a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return false;
1839a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  result->database_id_ = prefix.database_id_;
1840a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  result->object_store_id_ = prefix.object_store_id_;
1841a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1842a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return true;
1843a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
1844a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1845a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool BlobEntryKey::FromObjectStoreDataKey(StringPiece* slice,
1846a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                          BlobEntryKey* result) {
1847a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  KeyPrefix prefix;
1848a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!KeyPrefix::Decode(slice, &prefix))
1849a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return false;
1850a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(prefix.database_id_);
1851a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(prefix.object_store_id_);
1852a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK_EQ(prefix.index_id_, ObjectStoreDataKey::kSpecialIndexNumber);
1853a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1854a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!ExtractEncodedIDBKey(slice, &result->encoded_user_key_))
1855a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return false;
1856a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  result->database_id_ = prefix.database_id_;
1857a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  result->object_store_id_ = prefix.object_store_id_;
1858a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return true;
1859a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
1860a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1861a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)std::string BlobEntryKey::ReencodeToObjectStoreDataKey(StringPiece* slice) {
1862a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // TODO(ericu): We could be more efficient here, since the suffix is the same.
1863a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  BlobEntryKey key;
1864a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!Decode(slice, &key))
1865a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return std::string();
1866a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1867a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return ObjectStoreDataKey::Encode(
1868a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      key.database_id_, key.object_store_id_, key.encoded_user_key_);
1869a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
1870a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1871a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)std::string BlobEntryKey::EncodeMinKeyForObjectStore(int64 database_id,
1872a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                                     int64 object_store_id) {
1873a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Our implied encoded_user_key_ here is empty, the lowest possible key.
1874a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return Encode(database_id, object_store_id, std::string());
1875a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
1876a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1877a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)std::string BlobEntryKey::EncodeStopKeyForObjectStore(int64 database_id,
1878a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                                      int64 object_store_id) {
1879a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(KeyPrefix::ValidIds(database_id, object_store_id));
1880a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  KeyPrefix prefix(KeyPrefix::CreateWithSpecialIndex(
1881a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      database_id, object_store_id, kSpecialIndexNumber + 1));
1882a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return prefix.Encode();
1883a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
1884a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1885a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)std::string BlobEntryKey::Encode() const {
1886a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(!encoded_user_key_.empty());
1887a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return Encode(database_id_, object_store_id_, encoded_user_key_);
1888a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
1889a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1890a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)std::string BlobEntryKey::Encode(int64 database_id,
1891a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                 int64 object_store_id,
1892a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                 const IndexedDBKey& user_key) {
1893a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::string encoded_key;
1894a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EncodeIDBKey(user_key, &encoded_key);
1895a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return Encode(database_id, object_store_id, encoded_key);
1896a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
1897a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1898a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)std::string BlobEntryKey::Encode(int64 database_id,
1899a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                 int64 object_store_id,
1900a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                 const std::string& encoded_user_key) {
1901a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(KeyPrefix::ValidIds(database_id, object_store_id));
1902a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  KeyPrefix prefix(KeyPrefix::CreateWithSpecialIndex(
1903a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      database_id, object_store_id, kSpecialIndexNumber));
1904a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return prefix.Encode() + encoded_user_key;
1905a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
1906a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1907a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const int64 BlobEntryKey::kSpecialIndexNumber = kBlobEntryIndexId;
1908a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1909868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)IndexDataKey::IndexDataKey()
1910868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    : database_id_(-1),
1911868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      object_store_id_(-1),
1912868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      index_id_(-1),
1913868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      sequence_number_(-1) {}
1914868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1915868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)IndexDataKey::~IndexDataKey() {}
1916868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1917ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbool IndexDataKey::Decode(StringPiece* slice, IndexDataKey* result) {
1918868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  KeyPrefix prefix;
1919ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!KeyPrefix::Decode(slice, &prefix))
1920ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
1921868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(prefix.database_id_);
1922868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(prefix.object_store_id_);
1923868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK_GE(prefix.index_id_, kMinimumIndexId);
1924868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  result->database_id_ = prefix.database_id_;
1925868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  result->object_store_id_ = prefix.object_store_id_;
1926868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  result->index_id_ = prefix.index_id_;
1927868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  result->sequence_number_ = -1;
1928868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  result->encoded_primary_key_ = MinIDBKey();
1929868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1930ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!ExtractEncodedIDBKey(slice, &result->encoded_user_key_))
1931ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
1932868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1933868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // [optional] sequence number
1934ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (slice->empty())
1935ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return true;
1936ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!DecodeVarInt(slice, &result->sequence_number_))
1937ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
1938868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1939868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // [optional] primary key
1940ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (slice->empty())
1941ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return true;
1942ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!ExtractEncodedIDBKey(slice, &result->encoded_primary_key_))
1943ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
1944ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return true;
1945868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1946868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
19477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstd::string IndexDataKey::Encode(int64 database_id,
19487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                 int64 object_store_id,
19497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                 int64 index_id,
19507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                 const std::string& encoded_user_key,
19517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                 const std::string& encoded_primary_key,
19527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                 int64 sequence_number) {
1953868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  KeyPrefix prefix(database_id, object_store_id, index_id);
19547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::string ret = prefix.Encode();
19557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ret.append(encoded_user_key);
1956868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EncodeVarInt(sequence_number, &ret);
19577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ret.append(encoded_primary_key);
1958868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return ret;
1959868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1960868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
19617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstd::string IndexDataKey::Encode(int64 database_id,
19627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                 int64 object_store_id,
19637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                 int64 index_id,
19647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                 const IndexedDBKey& user_key) {
19657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::string encoded_key;
1966868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EncodeIDBKey(user_key, &encoded_key);
1967868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return Encode(
1968eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      database_id, object_store_id, index_id, encoded_key, MinIDBKey(), 0);
1969868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1970868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1971f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)std::string IndexDataKey::Encode(int64 database_id,
1972f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                 int64 object_store_id,
1973f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                 int64 index_id,
1974f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                 const IndexedDBKey& user_key,
1975f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                 const IndexedDBKey& user_primary_key) {
1976f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string encoded_key;
1977f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EncodeIDBKey(user_key, &encoded_key);
1978f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string encoded_primary_key;
1979f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EncodeIDBKey(user_primary_key, &encoded_primary_key);
1980f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return Encode(database_id,
1981f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                object_store_id,
1982f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                index_id,
1983f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                encoded_key,
1984f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                encoded_primary_key,
1985f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                0);
1986f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
1987f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
19887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstd::string IndexDataKey::EncodeMinKey(int64 database_id,
19897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                       int64 object_store_id,
19907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                       int64 index_id) {
1991868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return Encode(
1992eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      database_id, object_store_id, index_id, MinIDBKey(), MinIDBKey(), 0);
1993868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1994868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
19957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstd::string IndexDataKey::EncodeMaxKey(int64 database_id,
19967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                       int64 object_store_id,
19977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                       int64 index_id) {
1998868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return Encode(database_id,
1999868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                object_store_id,
2000868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                index_id,
2001868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                MaxIDBKey(),
2002868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                MaxIDBKey(),
2003868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                std::numeric_limits<int64>::max());
2004868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
2005868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2006868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int64 IndexDataKey::DatabaseId() const {
2007868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK_GE(database_id_, 0);
2008868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return database_id_;
2009868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
2010868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2011868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int64 IndexDataKey::ObjectStoreId() const {
2012868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK_GE(object_store_id_, 0);
2013868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return object_store_id_;
2014868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
2015868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2016868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int64 IndexDataKey::IndexId() const {
2017868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK_GE(index_id_, 0);
2018868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return index_id_;
2019868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
2020868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2021868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)scoped_ptr<IndexedDBKey> IndexDataKey::user_key() const {
2022868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<IndexedDBKey> key;
20237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  StringPiece slice(encoded_user_key_);
2024868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!DecodeIDBKey(&slice, &key)) {
2025868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // TODO(jsbell): Return error.
2026868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
2027868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return key.Pass();
2028868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
2029868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2030868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)scoped_ptr<IndexedDBKey> IndexDataKey::primary_key() const {
2031868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<IndexedDBKey> key;
20327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  StringPiece slice(encoded_primary_key_);
2033868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!DecodeIDBKey(&slice, &key)) {
2034868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // TODO(jsbell): Return error.
2035868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
2036868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return key.Pass();
2037868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
2038868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2039868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}  // namespace content
2040