Chromium Code Reviews| Index: content/browser/indexed_db/indexed_db_leveldb_coding.cc |
| diff --git a/content/browser/indexed_db/indexed_db_leveldb_coding.cc b/content/browser/indexed_db/indexed_db_leveldb_coding.cc |
| index d7f5bbf13f8424d3c61f57f5883c2e338c48a3b8..6ad2c9e4b028ddc80d0a069de000e0ff7c873b68 100644 |
| --- a/content/browser/indexed_db/indexed_db_leveldb_coding.cc |
| +++ b/content/browser/indexed_db/indexed_db_leveldb_coding.cc |
| @@ -44,6 +44,12 @@ |
| // <0, 0, 0, 0> => backing store schema version [SchemaVersionKey] |
| // <0, 0, 0, 1> => maximum allocated database [MaxDatabaseIdKey] |
| // <0, 0, 0, 2> => SerializedScriptValue version [DataVersionKey] |
| +// <0, 0, 0, 3> |
| +// => Blob journal |
| +// The format of the journal is: {database_id, blobKey}*. |
| +// If the blobKey is AllBlobsKey, the whole database should be deleted. |
|
cmumford
2014/03/13 17:53:41
kAllBlobsKey?
ericu
2014/03/13 19:25:45
Done.
|
| +// [BlobJournalKey] |
| +// <0, 0, 0, 4> => Live blob journal; same format. [LiveBlobJournalKey] |
| // <0, 0, 0, 100, database id> |
| // => Existence implies the database id is in the free list |
| // [DatabaseFreeListKey] |
| @@ -59,6 +65,7 @@ |
| // <database id, 0, 0, 2> => IDB string version data (obsolete) |
| // <database id, 0, 0, 3> => maximum allocated object store id |
| // <database id, 0, 0, 4> => IDB integer version (var int) |
| +// <database id, 0, 0, 5> => blob key generator current number |
| // |
| // |
| // Object store metadata: [ObjectStoreMetaDataKey] |
| @@ -133,6 +140,14 @@ |
| // <database id, object store id, 2, user key> => "version" |
| // |
| // |
| +// Blob entry table: [BlobEntryKey] |
| +// -------------------------------- |
| +// |
| +// The prefix is followed by a type byte and the encoded IDB primary key. |
| +// |
| +// <database id, object store id, 3, user key> => array of IndexedDBBlobInfo |
| +// |
| +// |
| // Index data |
| // ---------- |
| // The prefix is followed by a type byte, the encoded IDB index key, a |
| @@ -145,7 +160,6 @@ |
| // same user (index) key in non-unique indexes prior to the inclusion of the |
| // primary key in the data. |
| - |
| using base::StringPiece; |
| using blink::WebIDBKeyType; |
| using blink::WebIDBKeyTypeArray; |
| @@ -164,8 +178,8 @@ using blink::WebIDBKeyPathTypeString; |
| namespace content { |
| // As most of the IndexedDBKeys and encoded values are short, we |
| -// initialize some Vectors with a default inline buffer size to reduce |
| -// the memory re-allocations when the Vectors are appended. |
| +// initialize some std::vectors with a default inline buffer size to reduce |
| +// the memory re-allocations when the std::vectors are appended. |
| static const size_t kDefaultInlineBufferSize = 32; |
| static const unsigned char kIndexedDBKeyNullTypeByte = 0; |
| @@ -181,12 +195,15 @@ static const unsigned char kIndexedDBKeyPathTypeCodedByte2 = 0; |
| static const unsigned char kObjectStoreDataIndexId = 1; |
| static const unsigned char kExistsEntryIndexId = 2; |
| +static const unsigned char kBlobEntryIndexId = 3; |
| static const unsigned char kSchemaVersionTypeByte = 0; |
| static const unsigned char kMaxDatabaseIdTypeByte = 1; |
| static const unsigned char kDataVersionTypeByte = 2; |
| +static const unsigned char kBlobJournalTypeByte = 3; |
| +static const unsigned char kLiveBlobJournalTypeByte = 4; |
| static const unsigned char kMaxSimpleGlobalMetaDataTypeByte = |
| - 3; // Insert before this and increment. |
| + 5; // Insert before this and increment. |
| static const unsigned char kDatabaseFreeListTypeByte = 100; |
| static const unsigned char kDatabaseNameTypeByte = 201; |
| @@ -878,6 +895,14 @@ int CompareSuffix<ObjectStoreDataKey>(StringPiece* slice_a, |
| } |
| template <> |
| +int CompareSuffix<BlobEntryKey>(StringPiece* slice_a, |
| + StringPiece* slice_b, |
| + bool only_compare_index_keys, |
| + bool* ok) { |
| + return CompareEncodedIDBKeys(slice_a, slice_b, ok); |
| +} |
| + |
| +template <> |
| int CompareSuffix<IndexDataKey>(StringPiece* slice_a, |
| StringPiece* slice_b, |
| bool only_compare_index_keys, |
| @@ -1038,6 +1063,15 @@ int Compare(const StringPiece& a, |
| &slice_a, &slice_b, /*only_compare_index_keys*/ false, ok); |
| } |
| + case KeyPrefix::BLOB_ENTRY: { |
| + // Provide a stable ordering for invalid data. |
| + if (slice_a.empty() || slice_b.empty()) |
| + return CompareSizes(slice_a.size(), slice_b.size()); |
| + |
| + return CompareSuffix<BlobEntryKey>( |
| + &slice_a, &slice_b, /*only_compare_index_keys*/ false, ok); |
| + } |
| + |
| case KeyPrefix::INDEX_DATA: { |
| // Provide a stable ordering for invalid data. |
| if (slice_a.empty() || slice_b.empty()) |
| @@ -1239,6 +1273,8 @@ KeyPrefix::Type KeyPrefix::type() const { |
| return OBJECT_STORE_DATA; |
| if (index_id_ == kExistsEntryIndexId) |
| return EXISTS_ENTRY; |
| + if (index_id_ == kBlobEntryIndexId) |
| + return BLOB_ENTRY; |
| if (index_id_ >= kMinimumIndexId) |
| return INDEX_DATA; |
| @@ -1264,6 +1300,18 @@ std::string DataVersionKey::Encode() { |
| return ret; |
| } |
| +std::string BlobJournalKey::Encode() { |
| + std::string ret = KeyPrefix::EncodeEmpty(); |
| + ret.push_back(kBlobJournalTypeByte); |
| + return ret; |
| +} |
| + |
| +std::string LiveBlobJournalKey::Encode() { |
| + std::string ret = KeyPrefix::EncodeEmpty(); |
| + ret.push_back(kLiveBlobJournalTypeByte); |
| + return ret; |
| +} |
| + |
| DatabaseFreeListKey::DatabaseFreeListKey() : database_id_(-1) {} |
| bool DatabaseFreeListKey::Decode(StringPiece* slice, |
| @@ -1348,6 +1396,10 @@ int DatabaseNameKey::Compare(const DatabaseNameKey& other) { |
| return database_name_.compare(other.database_name_); |
| } |
| +bool DatabaseMetaDataKey::IsValidBlobKey(int64 blob_key) { |
| + return blob_key >= kBlobKeyGeneratorInitialNumber; |
| +} |
| + |
| std::string DatabaseMetaDataKey::Encode(int64 database_id, |
| MetaDataType meta_data_type) { |
| KeyPrefix prefix(database_id); |
| @@ -1747,6 +1799,87 @@ scoped_ptr<IndexedDBKey> ExistsEntryKey::user_key() const { |
| const int64 ExistsEntryKey::kSpecialIndexNumber = kExistsEntryIndexId; |
| +bool BlobEntryKey::Decode(StringPiece* slice, BlobEntryKey* result) { |
| + KeyPrefix prefix; |
| + if (!KeyPrefix::Decode(slice, &prefix)) |
| + return false; |
| + DCHECK(prefix.database_id_); |
| + DCHECK(prefix.object_store_id_); |
| + DCHECK_EQ(prefix.index_id_, kSpecialIndexNumber); |
| + |
| + if (!ExtractEncodedIDBKey(slice, &result->encoded_user_key_)) |
| + return false; |
| + result->database_id_ = prefix.database_id_; |
| + result->object_store_id_ = prefix.object_store_id_; |
| + |
| + return true; |
| +} |
| + |
| +bool BlobEntryKey::FromObjectStoreDataKey(StringPiece* slice, |
| + BlobEntryKey* result) { |
| + KeyPrefix prefix; |
| + if (!KeyPrefix::Decode(slice, &prefix)) |
| + return false; |
| + DCHECK(prefix.database_id_); |
| + DCHECK(prefix.object_store_id_); |
| + DCHECK_EQ(prefix.index_id_, ObjectStoreDataKey::kSpecialIndexNumber); |
| + |
| + if (!ExtractEncodedIDBKey(slice, &result->encoded_user_key_)) |
| + return false; |
| + result->database_id_ = prefix.database_id_; |
| + result->object_store_id_ = prefix.object_store_id_; |
| + return true; |
| +} |
| + |
| +std::string BlobEntryKey::ReencodeToObjectStoreDataKey(StringPiece* slice) { |
| + BlobEntryKey key; |
| + if (!Decode(slice, &key)) |
| + return std::string(); |
| + |
| + return ObjectStoreDataKey::Encode( |
| + key.database_id_, key.object_store_id_, key.encoded_user_key_); |
| +} |
| + |
| +std::string BlobEntryKey::EncodeMinKeyForObjectStore(int64 database_id, |
| + int64 object_store_id) { |
| + // Our implied encoded_user_key_ here is empty, the lowest possible key. |
| + return Encode(database_id, object_store_id, std::string()); |
| +} |
| + |
| +std::string BlobEntryKey::EncodeStopKeyForObjectStore(int64 database_id, |
| + int64 object_store_id) { |
| + DCHECK(KeyPrefix::ValidIds(database_id, object_store_id)); |
| + KeyPrefix prefix(KeyPrefix::CreateWithSpecialIndex( |
| + database_id, object_store_id, kSpecialIndexNumber + 1)); |
| + return prefix.Encode(); |
| +} |
| + |
| +std::string BlobEntryKey::Encode() const { |
| + DCHECK_GT(encoded_user_key_.size(), 0UL); |
|
cmumford
2014/03/13 17:53:41
Why not 4UL?
ericu
2014/03/13 19:25:45
That's not the lower limit of key length. Empty a
|
| + return Encode(database_id_, object_store_id_, encoded_user_key_); |
| +} |
| + |
| +std::string BlobEntryKey::Encode(int64 database_id, |
| + int64 object_store_id, |
| + const IndexedDBKey& user_key) { |
| + std::string encoded_key; |
| + EncodeIDBKey(user_key, &encoded_key); |
| + return Encode(database_id, object_store_id, encoded_key); |
| +} |
| + |
| +std::string BlobEntryKey::Encode(int64 database_id, |
| + int64 object_store_id, |
| + const std::string& encoded_user_key) { |
| + DCHECK(KeyPrefix::ValidIds(database_id, object_store_id)); |
| + KeyPrefix prefix(KeyPrefix::CreateWithSpecialIndex( |
| + database_id, object_store_id, kSpecialIndexNumber)); |
| + std::string ret = prefix.Encode(); |
| + ret.insert(ret.end(), encoded_user_key.begin(), encoded_user_key.end()); |
| + return ret; |
|
cmumford
2014/03/13 17:53:41
Why not just?
return prefix.Encode() + encoded_us
ericu
2014/03/13 19:25:45
Why indeed?
I think this is leftover from when th
jsbell
2014/03/13 20:58:48
Yep. These were originally Vector<char> then std::
|
| +} |
| + |
| +const int64 BlobEntryKey::kSpecialIndexNumber = kBlobEntryIndexId; |
| + |
| IndexDataKey::IndexDataKey() |
| : database_id_(-1), |
| object_store_id_(-1), |