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

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: 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_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_;
};

Powered by Google App Engine
This is Rietveld 408576698