Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2729)

Unified Diff: content/browser/indexed_db/indexed_db_leveldb_coding.cc

Issue 18023022: Blob support for IDB [Chromium] (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Merge fixes [builds, untested] Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 3a7028012a37beb119db04d8401a8397a684423a..716ccfe3c674688447a097b40b9346a141ec361f 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.
+// [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
@@ -163,8 +178,8 @@ using WebKit::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;
@@ -179,12 +194,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;
@@ -858,6 +876,34 @@ int Compare<ObjectStoreDataKey>(const StringPiece& a,
}
template <>
+int Compare<BlobEntryKey>(const StringPiece& a,
+ const StringPiece& b,
+ bool,
+ bool* ok) {
+ KeyPrefix prefix_a;
+ KeyPrefix prefix_b;
+ StringPiece slice_a(a);
+ StringPiece slice_b(b);
+ bool ok_a = KeyPrefix::Decode(&slice_a, &prefix_a);
+ bool ok_b = KeyPrefix::Decode(&slice_b, &prefix_b);
+ DCHECK(ok_a);
+ DCHECK(ok_b);
+ DCHECK(prefix_a.database_id_);
+ DCHECK(prefix_a.object_store_id_);
+ DCHECK_EQ(prefix_a.index_id_, BlobEntryKey::kSpecialIndexNumber);
+ DCHECK(prefix_b.database_id_);
+ DCHECK(prefix_b.object_store_id_);
+ DCHECK_EQ(prefix_b.index_id_, BlobEntryKey::kSpecialIndexNumber);
+ DCHECK(!slice_a.empty());
+ DCHECK(!slice_b.empty());
+ // Prefixes are not compared - it is assumed this was already done.
+ DCHECK(!prefix_a.Compare(prefix_b));
+
+ return CompareSuffix<ObjectStoreDataKey>(
+ &slice_a, &slice_b, false, ok);
+}
+
+template <>
int CompareSuffix<IndexDataKey>(StringPiece* slice_a,
StringPiece* slice_b,
bool only_compare_index_keys,
@@ -1036,6 +1082,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())
@@ -1237,6 +1292,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;
@@ -1262,6 +1319,20 @@ 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,
@@ -1346,6 +1417,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);
@@ -1752,6 +1827,103 @@ 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::EncodeToObjectStoreDataKey(StringPiece* slice) {
jsbell 2013/09/13 00:12:21 What this method did wasn't obvious to me at the c
ericu 2013/11/20 23:05:39 Done.
+ 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::EncodeMinForObjectStore(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());
+}
+
+// This isn't technically the max for this object store--it's one higher, which
+// means that it's the first key /not/ in the range. That's more what we want,
+// but doesn't match the terminology elsewhere in this file, which is a bit
+// messy.
+std::string BlobEntryKey::EncodeMaxForObjectStore(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));
jsbell 2013/09/13 00:12:21 Can you introduce another const, rather than kSpec
ericu 2013/11/20 23:05:39 I think that might be confusing. The point is not
jsbell 2013/11/21 22:54:32 Got it, I wasn't paying attention to the usage (i.
+ return prefix.Encode();
+}
+
+std::string BlobEntryKey::Encode() const
+{
+ DCHECK_GT(encoded_user_key_.size(), 0UL);
+ 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;
+}
+
+int BlobEntryKey::Compare(const BlobEntryKey& other, bool* ok)
+{
+ DCHECK_GT(encoded_user_key_.size(), 0UL);
+ DCHECK_GT(other.encoded_user_key_.size(), 0UL);
+ return CompareEncodedIDBKeys(encoded_user_key_, other.encoded_user_key_, ok);
+}
+
+const int64 BlobEntryKey::kSpecialIndexNumber = kBlobEntryIndexId;
+
IndexDataKey::IndexDataKey()
: database_id_(-1),
object_store_id_(-1),

Powered by Google App Engine
This is Rietveld 408576698