| 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 7169d21cbbc6433555578cbe8d4cf00f675a0e59..2eed735d38de71329069b7576eafc5679483987c 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>
|
|
|
| @@ -13,7 +14,11 @@
|
| #include "base/memory/ref_counted.h"
|
| #include "base/memory/scoped_ptr.h"
|
| #include "base/memory/weak_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 +29,21 @@
|
| #include "third_party/WebKit/public/platform/WebIDBCallbacks.h"
|
| #include "third_party/leveldatabase/src/include/leveldb/status.h"
|
|
|
| +class GURL;
|
| +
|
| +namespace base {
|
| +class TaskRunner;
|
| +}
|
| +
|
| +namespace net {
|
| +class URLRequestContext;
|
| +}
|
| +
|
| namespace content {
|
|
|
| class LevelDBComparator;
|
| class LevelDBDatabase;
|
| +struct IndexedDBValue;
|
|
|
| class LevelDBFactory {
|
| public:
|
| @@ -49,14 +65,20 @@ class CONTENT_EXPORT IndexedDBBackingStore
|
| const std::string& origin_identifier,
|
| const base::FilePath& path_base,
|
| const std::string& file_identifier,
|
| - WebKit::WebIDBCallbacks::DataLoss* data_loss);
|
| + net::URLRequestContext* request_context,
|
| + WebKit::WebIDBCallbacks::DataLoss* data_loss,
|
| + base::TaskRunner* task_runner,
|
| + bool clean_journal);
|
|
|
| static scoped_refptr<IndexedDBBackingStore> Open(
|
| const std::string& origin_identifier,
|
| const base::FilePath& path_base,
|
| const std::string& file_identifier,
|
| + net::URLRequestContext* request_context,
|
| WebKit::WebIDBCallbacks::DataLoss* data_loss,
|
| - LevelDBFactory* factory);
|
| + LevelDBFactory* factory,
|
| + base::TaskRunner* task_runner,
|
| + bool clean_journal);
|
| static scoped_refptr<IndexedDBBackingStore> OpenInMemory(
|
| const std::string& file_identifier);
|
| static scoped_refptr<IndexedDBBackingStore> OpenInMemory(
|
| @@ -66,6 +88,8 @@ class CONTENT_EXPORT IndexedDBBackingStore
|
| return weak_factory_.GetWeakPtr();
|
| }
|
|
|
| + void GrantChildProcessPermissions(int child_process_id);
|
| +
|
| virtual std::vector<string16> GetDatabaseNames();
|
| virtual bool GetIDBDatabaseMetaData(const string16& name,
|
| IndexedDBDatabaseMetadata* metadata,
|
| @@ -120,16 +144,23 @@ 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,
|
| RecordIdentifier* record) WARN_UNUSED_RESULT;
|
| virtual bool ClearObjectStore(IndexedDBBackingStore::Transaction* transaction,
|
| int64 database_id,
|
| @@ -138,6 +169,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,
|
| @@ -191,6 +226,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();
|
| @@ -222,12 +262,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);
|
|
|
| @@ -236,7 +278,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_;
|
| @@ -275,35 +319,146 @@ 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>*);
|
|
|
| static LevelDBTransaction* LevelDBTransactionFrom(
|
| Transaction* transaction) {
|
| return transaction->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:
|
| + struct AVLTreeNode {
|
| + AVLTreeNode() {}
|
| + ~AVLTreeNode() {}
|
| + std::string key;
|
| + int64 object_store_id;
|
| + std::vector<IndexedDBBlobInfo> blob_info;
|
| +
|
| + AVLTreeNode* less;
|
| + AVLTreeNode* greater;
|
| + int balance_factor;
|
| + DISALLOW_COPY_AND_ASSIGN(AVLTreeNode);
|
| + };
|
| + struct AVLTreeAbstractor {
|
| + typedef AVLTreeNode* handle;
|
| + typedef size_t size;
|
| + typedef std::string key; // TODO(ericu): base::StringPiece?
|
| +
|
| + handle GetLess(handle h) { return h->less; }
|
| + void SetLess(handle h, handle less) { h->less = less; }
|
| + handle GetGreater(handle h) { return h->greater; }
|
| + void SetGreater(handle h, handle greater) { h->greater = greater; }
|
| +
|
| + int GetBalanceFactor(handle h) { return h->balance_factor; }
|
| + void SetBalanceFactor(handle h, int bf) { h->balance_factor = bf; }
|
| +
|
| + int CompareKeyKey(const key& ka, const key& kb) {
|
| + return comparator_->Compare(ka, kb);
|
| + }
|
| + int CompareKeyNode(const key& k, handle h) {
|
| + return CompareKeyKey(k, key(h->key));
|
| + }
|
| + int CompareNodeNode(handle ha, handle hb) {
|
| + return CompareKeyKey(key(ha->key), key(hb->key));
|
| + }
|
| +
|
| + static handle Null() { return 0; }
|
| +
|
| + const LevelDBComparator* comparator_;
|
| + };
|
| + typedef AVLTree<AVLTreeAbstractor> TreeType;
|
| +
|
| + // 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_;
|
| + TreeType blob_info_tree_;
|
| + 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 std::string& identifier,
|
| + 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(
|
| const std::string& identifier,
|
| + 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,
|
| @@ -316,11 +471,23 @@ 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();
|
|
|
| std::string 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::WeakPtrFactory<IndexedDBBackingStore> weak_factory_;
|
| };
|
|
|
|
|