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

Unified Diff: content/browser/indexed_db/indexed_db_backing_store.h

Issue 18023022: Blob support for IDB [Chromium] (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Settle on one name for the live blob journal. Created 7 years 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_backing_store.h
diff --git a/content/browser/indexed_db/indexed_db_backing_store.h b/content/browser/indexed_db/indexed_db_backing_store.h
index 9ea71f11ac65fd6b18c42b5734b9cf320bd9fcf2..255af25dbda86cbb011cdb38d5dd8b21b850ebe9 100644
--- a/content/browser/indexed_db/indexed_db_backing_store.h
+++ b/content/browser/indexed_db/indexed_db_backing_store.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_BACKING_STORE_H_
#define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_BACKING_STORE_H_
+#include <set>
#include <string>
#include <vector>
@@ -14,6 +15,9 @@
#include "base/memory/scoped_ptr.h"
#include "base/timer/timer.h"
#include "content/browser/indexed_db/indexed_db.h"
+#include "content/browser/indexed_db/indexed_db_active_blob_registry.h"
+#include "content/browser/indexed_db/indexed_db_blob_info.h"
+#include "content/browser/indexed_db/indexed_db_leveldb_coding.h"
#include "content/browser/indexed_db/indexed_db_metadata.h"
#include "content/browser/indexed_db/leveldb/leveldb_iterator.h"
#include "content/browser/indexed_db/leveldb/leveldb_transaction.h"
@@ -24,10 +28,26 @@
#include "third_party/leveldatabase/src/include/leveldb/status.h"
#include "url/gurl.h"
+class GURL;
+
+namespace base {
+class TaskRunner;
+}
+
+namespace net {
+class URLRequestContext;
+}
+
+namespace webkit_blob {
+class BlobDataHandle;
+}
+
namespace content {
+class IndexedDBFactory;
class LevelDBComparator;
class LevelDBDatabase;
+struct IndexedDBValue;
class LevelDBFactory {
public:
@@ -48,27 +68,38 @@ class CONTENT_EXPORT IndexedDBBackingStore
base::OneShotTimer<IndexedDBBackingStore>* close_timer() {
return &close_timer_;
}
+ IndexedDBFactory* factory() const { return indexed_db_factory_; }
static scoped_refptr<IndexedDBBackingStore> Open(
+ IndexedDBFactory* indexed_db_factory,
const GURL& origin_url,
const base::FilePath& path_base,
+ net::URLRequestContext* request_context,
blink::WebIDBDataLoss* data_loss,
std::string* data_loss_message,
- bool* disk_full);
+ bool* disk_full,
+ base::TaskRunner* task_runner,
+ bool clean_journal);
static scoped_refptr<IndexedDBBackingStore> Open(
+ IndexedDBFactory* indexed_db_factory,
const GURL& origin_url,
const base::FilePath& path_base,
+ net::URLRequestContext* request_context,
blink::WebIDBDataLoss* data_loss,
std::string* data_loss_message,
bool* disk_full,
- LevelDBFactory* factory);
+ LevelDBFactory* factory,
+ base::TaskRunner* task_runner,
+ bool clean_journal);
static scoped_refptr<IndexedDBBackingStore> OpenInMemory(
const GURL& origin_url);
static scoped_refptr<IndexedDBBackingStore> OpenInMemory(
const GURL& origin_url,
LevelDBFactory* factory);
+ void GrantChildProcessPermissions(int child_process_id);
+
virtual std::vector<string16> GetDatabaseNames();
virtual bool GetIDBDatabaseMetaData(const string16& name,
IndexedDBDatabaseMetadata* metadata,
@@ -119,16 +150,24 @@ class CONTENT_EXPORT IndexedDBBackingStore
DISALLOW_COPY_AND_ASSIGN(RecordIdentifier);
};
+ class BlobWriteCallback : public RefCounted<BlobWriteCallback> {
+ public:
+ virtual ~BlobWriteCallback() { }
+ virtual void didSucceed() = 0;
+ virtual void didFail() = 0;
+ };
+
virtual bool GetRecord(IndexedDBBackingStore::Transaction* transaction,
int64 database_id,
int64 object_store_id,
const IndexedDBKey& key,
- std::string* record) WARN_UNUSED_RESULT;
+ IndexedDBValue* record) WARN_UNUSED_RESULT;
virtual bool PutRecord(IndexedDBBackingStore::Transaction* transaction,
int64 database_id,
int64 object_store_id,
const IndexedDBKey& key,
- const std::string& value,
+ IndexedDBValue& value,
+ std::vector<webkit_blob::BlobDataHandle*>* handles,
RecordIdentifier* record) WARN_UNUSED_RESULT;
virtual bool ClearObjectStore(IndexedDBBackingStore::Transaction* transaction,
int64 database_id,
@@ -137,6 +176,10 @@ class CONTENT_EXPORT IndexedDBBackingStore
int64 database_id,
int64 object_store_id,
const RecordIdentifier& record) WARN_UNUSED_RESULT;
+ virtual bool DeleteRange(IndexedDBBackingStore::Transaction* transaction,
+ int64 database_id,
+ int64 object_store_id,
+ const IndexedDBKeyRange&) WARN_UNUSED_RESULT;
virtual bool GetKeyGeneratorCurrentNumber(
IndexedDBBackingStore::Transaction* transaction,
int64 database_id,
@@ -190,6 +233,11 @@ class CONTENT_EXPORT IndexedDBBackingStore
scoped_ptr<IndexedDBKey>* found_primary_key,
bool* exists) WARN_UNUSED_RESULT;
+ // Public for IndexedDBBlobRegistryCallback.
+ void ReportBlobUnused(int64 database_id, int64 blob_key);
+
+ base::FilePath GetIDBBlobFileName(int64 database_id, int64 key);
+
class Cursor {
public:
virtual ~Cursor();
@@ -226,12 +274,14 @@ class CONTENT_EXPORT IndexedDBBackingStore
virtual Cursor* Clone() = 0;
virtual const IndexedDBKey& primary_key() const;
- virtual std::string* Value() = 0;
+ virtual IndexedDBValue* Value() = 0;
virtual const RecordIdentifier& record_identifier() const;
virtual bool LoadCurrentRow() = 0;
protected:
- Cursor(LevelDBTransaction* transaction,
+ Cursor(scoped_refptr<IndexedDBBackingStore> backing_store,
+ LevelDBTransaction* transaction,
+ int64 database_id,
const CursorOptions& cursor_options);
explicit Cursor(const IndexedDBBackingStore::Cursor* other);
@@ -242,7 +292,9 @@ class CONTENT_EXPORT IndexedDBBackingStore
bool IsPastBounds() const;
bool HaveEnteredRange() const;
+ scoped_refptr<IndexedDBBackingStore> backing_store_;
LevelDBTransaction* transaction_;
+ int64 database_id_;
const CursorOptions cursor_options_;
scoped_ptr<LevelDBIterator> iterator_;
scoped_ptr<IndexedDBKey> current_key_;
@@ -281,32 +333,138 @@ class CONTENT_EXPORT IndexedDBBackingStore
explicit Transaction(IndexedDBBackingStore* backing_store);
~Transaction();
void Begin();
- bool Commit();
+ // The callback will be called eventually on success or failure, or
+ // immediately if phase one is complete due to lack of any blobs to write.
+ bool CommitPhaseOne(scoped_refptr<BlobWriteCallback>);
+ bool CommitPhaseTwo();
void Rollback();
void Reset() {
backing_store_ = NULL;
transaction_ = NULL;
}
+ void PutBlobInfo(int64 database_id, int64 object_store_id,
+ const std::string& key, std::vector<IndexedDBBlobInfo>*,
+ std::vector<webkit_blob::BlobDataHandle*>* handles);
LevelDBTransaction* transaction() { return transaction_; }
+ // DatabaseId, BlobKey
+ typedef std::pair<int64_t, int64_t> BlobJournalEntryType;
+ typedef std::vector<BlobJournalEntryType> BlobJournalType;
+ // This holds a BlobEntryKey and the encoded IndexedDBBlobInfo vector stored
+ // under that key.
+ typedef std::vector< std::pair<BlobEntryKey, std::string> >
+ BlobEntryKeyValuePairVec;
+
+ class WriteDescriptor {
+ public:
+ WriteDescriptor(const GURL& url, int64_t key);
+ WriteDescriptor(const base::FilePath& path, int64_t key);
+
+ bool is_file() const { return is_file_; }
+ const GURL& url() const {
+ DCHECK(!is_file_);
+ return url_;
+ }
+ const base::FilePath& file_path() const {
+ DCHECK(is_file_);
+ return file_path_;
+ }
+ int64_t key() const { return key_; }
+ private:
+ bool is_file_;
+ GURL url_;
+ base::FilePath file_path_;
+ int64_t key_;
+ };
+
+ class ChainedBlobWriter;
+
+ typedef std::vector<WriteDescriptor> WriteDescriptorVec;
+
private:
+ class BlobChangeRecord {
+ public:
+ BlobChangeRecord() {}
+ ~BlobChangeRecord();
+ void set_key(const std::string& key) {
+ key_ = key;
+ }
+ const std::string& key() const {
+ return key_;
+ }
+ void set_object_store_id(int64 object_store_id) {
+ object_store_id_ = object_store_id;
+ }
+ int64 object_store_id() const {
+ return object_store_id_;
+ }
+ void SetBlobInfo(std::vector<IndexedDBBlobInfo>* blob_info);
+ std::vector<IndexedDBBlobInfo>& mutable_blob_info() {
+ return blob_info_;
+ }
+ void SetHandles(std::vector<webkit_blob::BlobDataHandle*>* handles);
+
+ private:
+ void DeleteHandles();
+
+ std::string key_;
+ int64 object_store_id_;
+ std::vector<IndexedDBBlobInfo> blob_info_;
+ std::vector<webkit_blob::BlobDataHandle*> handles_;
+ };
+ class BlobWriteCallbackWrapper;
+ typedef std::map<std::string, BlobChangeRecord*> BlobChangeMap;
+
+ // These return true on success, false on failure.
+ bool HandleBlobPreTransaction(BlobEntryKeyValuePairVec* new_blob_entries,
+ WriteDescriptorVec* new_files_to_write);
+ bool CollectBlobFilesToRemove();
+ // The callback will be called eventually on success or failure.
+ void WriteNewBlobs(BlobEntryKeyValuePairVec& new_blob_entries,
+ WriteDescriptorVec& new_files_to_write,
+ scoped_refptr<BlobWriteCallback> callback);
+ bool SortBlobsToRemove();
+
IndexedDBBackingStore* backing_store_;
scoped_refptr<LevelDBTransaction> transaction_;
+ BlobChangeMap blob_change_map_;
+ int64 database_id_;
+ BlobJournalType blobs_to_remove_;
+ scoped_refptr<ChainedBlobWriter> chained_blob_writer_;
};
+ LevelDBComparator* comparator() { return comparator_.get(); }
+ IndexedDBActiveBlobRegistry* active_blob_registry() {
+ return &active_blob_registry_;
+ }
+
+ base::TaskRunner* task_runner() { return task_runner_; }
+
protected:
- IndexedDBBackingStore(const GURL& origin_url,
+ IndexedDBBackingStore(IndexedDBFactory* indexed_db_factory,
+ const GURL& origin_url,
+ const base::FilePath& blob_path,
+ net::URLRequestContext* request_context,
scoped_ptr<LevelDBDatabase> db,
- scoped_ptr<LevelDBComparator> comparator);
+ scoped_ptr<LevelDBComparator> comparator,
+ base::TaskRunner* task_runner);
virtual ~IndexedDBBackingStore();
friend class base::RefCounted<IndexedDBBackingStore>;
+ bool WriteBlobFile(int64 database_id,
+ const Transaction::WriteDescriptor& descriptor,
+ Transaction::ChainedBlobWriter* chained_blob_writer);
+
private:
static scoped_refptr<IndexedDBBackingStore> Create(
+ IndexedDBFactory* indexed_db_factory,
const GURL& origin_url,
+ const base::FilePath& blob_path,
+ net::URLRequestContext* request_context,
scoped_ptr<LevelDBDatabase> db,
- scoped_ptr<LevelDBComparator> comparator);
+ scoped_ptr<LevelDBComparator> comparator,
+ base::TaskRunner* task_runner);
bool FindKeyInIndex(IndexedDBBackingStore::Transaction* transaction,
int64 database_id,
@@ -319,7 +477,12 @@ class CONTENT_EXPORT IndexedDBBackingStore
int64 object_store_id,
IndexedDBObjectStoreMetadata::IndexMap* map)
WARN_UNUSED_RESULT;
+ bool RemoveBlobFile(int64 database_id, int64 key);
+ bool RemoveBlobDirectory(int64 database_id);
+ bool CleanUpBlobJournal(const std::string& level_db_key);
+ void CleanPrimaryJournalIgnoreReturn();
+ IndexedDBFactory* indexed_db_factory_;
const GURL origin_url_;
// The origin identifier is a key prefix unique to the origin used in the
@@ -330,8 +493,17 @@ class CONTENT_EXPORT IndexedDBBackingStore
// provides for future flexibility.
const std::string origin_identifier_;
+ base::FilePath blob_path_;
+ net::URLRequestContext* request_context_;
+ base::TaskRunner* task_runner_;
+ std::set<int> child_process_ids_granted_;
+ base::OneShotTimer<IndexedDBBackingStore> journal_cleaning_timer_;
+
scoped_ptr<LevelDBDatabase> db_;
scoped_ptr<LevelDBComparator> comparator_;
+ // The active_blob_registry_ will hold a refcount to this backing store
+ // whenever any live blobs are registered with it.
+ IndexedDBActiveBlobRegistry active_blob_registry_;
base::OneShotTimer<IndexedDBBackingStore> close_timer_;
};

Powered by Google App Engine
This is Rietveld 408576698