| 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..3fce9805b9036adf0afc582f4cf07a13d412ab8e 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"
|
| @@ -23,11 +27,28 @@
|
| #include "content/common/indexed_db/indexed_db_key_range.h"
|
| #include "third_party/leveldatabase/src/include/leveldb/status.h"
|
| #include "url/gurl.h"
|
| +#include "webkit/browser/blob/blob_data_handle.h"
|
| +
|
| +class GURL;
|
| +
|
| +namespace base {
|
| +class TaskRunner;
|
| +}
|
| +
|
| +namespace fileapi {
|
| +class FileWriterDelegate;
|
| +}
|
| +
|
| +namespace net {
|
| +class URLRequestContext;
|
| +}
|
|
|
| namespace content {
|
|
|
| +class IndexedDBFactory;
|
| class LevelDBComparator;
|
| class LevelDBDatabase;
|
| +struct IndexedDBValue;
|
|
|
| class LevelDBFactory {
|
| public:
|
| @@ -48,26 +69,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);
|
| + const GURL& origin_url, base::TaskRunner* task_runner);
|
| static scoped_refptr<IndexedDBBackingStore> OpenInMemory(
|
| const GURL& origin_url,
|
| - LevelDBFactory* factory);
|
| + LevelDBFactory* factory,
|
| + base::TaskRunner* task_runner);
|
| +
|
| + void GrantChildProcessPermissions(int child_process_id);
|
|
|
| virtual std::vector<string16> GetDatabaseNames();
|
| virtual bool GetIDBDatabaseMetaData(const string16& name,
|
| @@ -119,16 +152,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,
|
| + ScopedVector<webkit_blob::BlobDataHandle>* handles,
|
| RecordIdentifier* record) WARN_UNUSED_RESULT;
|
| virtual bool ClearObjectStore(IndexedDBBackingStore::Transaction* transaction,
|
| int64 database_id,
|
| @@ -137,6 +178,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 +235,11 @@ class CONTENT_EXPORT IndexedDBBackingStore
|
| scoped_ptr<IndexedDBKey>* found_primary_key,
|
| bool* exists) WARN_UNUSED_RESULT;
|
|
|
| + // Public for IndexedDBActiveBlobRegistry::ReleaseBlobRef.
|
| + void ReportBlobUnused(int64 database_id, int64 blob_key);
|
| +
|
| + base::FilePath GetIDBBlobFileName(int64 database_id, int64 key);
|
| +
|
| class Cursor {
|
| public:
|
| virtual ~Cursor();
|
| @@ -226,12 +276,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 +294,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 +335,155 @@ 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>*,
|
| + ScopedVector<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 : public base::RefCounted<ChainedBlobWriter> {
|
| + public:
|
| +
|
| + virtual void set_delegate(
|
| + scoped_ptr<fileapi::FileWriterDelegate> delegate) = 0;
|
| +
|
| + virtual void ReportWriteCompletion(
|
| + bool succeeded, int64 bytes_written) = 0;
|
| +
|
| + virtual void Abort() = 0;
|
| +
|
| + protected:
|
| + virtual ~ChainedBlobWriter() {}
|
| + friend class base::RefCounted<ChainedBlobWriter>;
|
| + };
|
| + class ChainedBlobWriterImpl;
|
| +
|
| + typedef std::vector<WriteDescriptor> WriteDescriptorVec;
|
| +
|
| private:
|
| + class BlobChangeRecord {
|
| + public:
|
| + 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(ScopedVector<webkit_blob::BlobDataHandle>* handles);
|
| +
|
| + private:
|
| + std::string key_;
|
| + int64 object_store_id_;
|
| + std::vector<IndexedDBBlobInfo> blob_info_;
|
| + ScopedVector<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 SetUpMetadata();
|
| +
|
| + virtual bool WriteBlobFile(
|
| + int64 database_id, const Transaction::WriteDescriptor& descriptor,
|
| + Transaction::ChainedBlobWriter* chained_blob_writer);
|
| + virtual bool RemoveBlobFile(int64 database_id, int64 key);
|
| + virtual void StartJournalCleaningTimer();
|
| + void CleanPrimaryJournalIgnoreReturn();
|
| +
|
| 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 +496,10 @@ class CONTENT_EXPORT IndexedDBBackingStore
|
| int64 object_store_id,
|
| IndexedDBObjectStoreMetadata::IndexMap* map)
|
| WARN_UNUSED_RESULT;
|
| + bool RemoveBlobDirectory(int64 database_id);
|
| + bool CleanUpBlobJournal(const std::string& level_db_key);
|
|
|
| + IndexedDBFactory* indexed_db_factory_;
|
| const GURL origin_url_;
|
|
|
| // The origin identifier is a key prefix unique to the origin used in the
|
| @@ -330,8 +510,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_;
|
| };
|
|
|
|
|