OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_BACKING_STORE_H_ | 5 #ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_BACKING_STORE_H_ |
6 #define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_BACKING_STORE_H_ | 6 #define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_BACKING_STORE_H_ |
7 | 7 |
8 #include <map> | 8 #include <map> |
9 #include <set> | 9 #include <set> |
10 #include <string> | 10 #include <string> |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 DISALLOW_COPY_AND_ASSIGN(BlobChangeRecord); | 116 DISALLOW_COPY_AND_ASSIGN(BlobChangeRecord); |
117 }; | 117 }; |
118 typedef std::map<std::string, BlobChangeRecord*> BlobChangeMap; | 118 typedef std::map<std::string, BlobChangeRecord*> BlobChangeMap; |
119 | 119 |
120 class CONTENT_EXPORT Transaction { | 120 class CONTENT_EXPORT Transaction { |
121 public: | 121 public: |
122 explicit Transaction(IndexedDBBackingStore* backing_store); | 122 explicit Transaction(IndexedDBBackingStore* backing_store); |
123 virtual ~Transaction(); | 123 virtual ~Transaction(); |
124 | 124 |
125 virtual void Begin(); | 125 virtual void Begin(); |
| 126 |
| 127 // CommitPhaseOne determines what blobs (if any) need to be written to disk |
| 128 // and updates the primary blob journal, and kicks off the async writing |
| 129 // of the blob files. In case of crash/rollback, the journal indicates what |
| 130 // files should be cleaned up. |
126 // The callback will be called eventually on success or failure, or | 131 // The callback will be called eventually on success or failure, or |
127 // immediately if phase one is complete due to lack of any blobs to write. | 132 // immediately if phase one is complete due to lack of any blobs to write. |
128 virtual leveldb::Status CommitPhaseOne(scoped_refptr<BlobWriteCallback>); | 133 virtual leveldb::Status CommitPhaseOne(scoped_refptr<BlobWriteCallback>); |
| 134 |
| 135 // CommitPhaseTwo is called once the blob files (if any) have been written |
| 136 // to disk, and commits the actual transaction to the backing store, |
| 137 // including blob journal updates, then deletes any blob files deleted |
| 138 // by the transaction and not referenced by running scripts. |
129 virtual leveldb::Status CommitPhaseTwo(); | 139 virtual leveldb::Status CommitPhaseTwo(); |
| 140 |
130 virtual void Rollback(); | 141 virtual void Rollback(); |
131 void Reset() { | 142 void Reset() { |
132 backing_store_ = NULL; | 143 backing_store_ = NULL; |
133 transaction_ = NULL; | 144 transaction_ = NULL; |
134 } | 145 } |
135 leveldb::Status PutBlobInfoIfNeeded( | 146 leveldb::Status PutBlobInfoIfNeeded( |
136 int64 database_id, | 147 int64 database_id, |
137 int64 object_store_id, | 148 int64 object_store_id, |
138 const std::string& object_store_data_key, | 149 const std::string& object_store_data_key, |
139 std::vector<IndexedDBBlobInfo>*, | 150 std::vector<IndexedDBBlobInfo>*, |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
206 virtual ~ChainedBlobWriter() {} | 217 virtual ~ChainedBlobWriter() {} |
207 }; | 218 }; |
208 | 219 |
209 class ChainedBlobWriterImpl; | 220 class ChainedBlobWriterImpl; |
210 | 221 |
211 typedef std::vector<WriteDescriptor> WriteDescriptorVec; | 222 typedef std::vector<WriteDescriptor> WriteDescriptorVec; |
212 | 223 |
213 private: | 224 private: |
214 class BlobWriteCallbackWrapper; | 225 class BlobWriteCallbackWrapper; |
215 | 226 |
| 227 // Called by CommitPhaseOne: Identifies the blob entries to write and adds |
| 228 // them to the primary blob journal directly (i.e. not as part of the |
| 229 // transaction). Populates blobs_to_write_. |
216 leveldb::Status HandleBlobPreTransaction( | 230 leveldb::Status HandleBlobPreTransaction( |
217 BlobEntryKeyValuePairVec* new_blob_entries, | 231 BlobEntryKeyValuePairVec* new_blob_entries, |
218 WriteDescriptorVec* new_files_to_write); | 232 WriteDescriptorVec* new_files_to_write); |
219 // Returns true on success, false on failure. | 233 |
| 234 // Called by CommitPhaseOne: Populates blob_files_to_remove_ by |
| 235 // determining which blobs are deleted as part of the transaction, and |
| 236 // adds blob entry cleanup operations to the transaction. Returns true on |
| 237 // success, false on failure. |
220 bool CollectBlobFilesToRemove(); | 238 bool CollectBlobFilesToRemove(); |
221 // The callback will be called eventually on success or failure. | 239 |
| 240 // Called by CommitPhaseOne: Kicks off the asynchronous writes of blobs |
| 241 // identified in HandleBlobPreTransaction. The callback will be called |
| 242 // eventually on success or failure. |
222 void WriteNewBlobs(BlobEntryKeyValuePairVec* new_blob_entries, | 243 void WriteNewBlobs(BlobEntryKeyValuePairVec* new_blob_entries, |
223 WriteDescriptorVec* new_files_to_write, | 244 WriteDescriptorVec* new_files_to_write, |
224 scoped_refptr<BlobWriteCallback> callback); | 245 scoped_refptr<BlobWriteCallback> callback); |
225 leveldb::Status SortBlobsToRemove(); | 246 |
| 247 // Called by CommitPhaseTwo: Partition blob references in blobs_to_remove_ |
| 248 // into live (active references) and dead (no references). |
| 249 void PartitionBlobsToRemove(BlobJournalType* dead_blobs, |
| 250 BlobJournalType* live_blobs) const; |
226 | 251 |
227 IndexedDBBackingStore* backing_store_; | 252 IndexedDBBackingStore* backing_store_; |
228 scoped_refptr<LevelDBTransaction> transaction_; | 253 scoped_refptr<LevelDBTransaction> transaction_; |
229 BlobChangeMap blob_change_map_; | 254 BlobChangeMap blob_change_map_; |
230 BlobChangeMap incognito_blob_map_; | 255 BlobChangeMap incognito_blob_map_; |
231 int64 database_id_; | 256 int64 database_id_; |
| 257 |
| 258 // List of blob files being newly written as part of this transaction. |
| 259 // These will be added to the primary blob journal prior to commit, then |
| 260 // removed after a sucessful commit. |
| 261 BlobJournalType blobs_to_write_; |
| 262 |
| 263 // List of blob files being deleted as part of this transaction. These will |
| 264 // be added to either the primary or live blob journal as appropriate |
| 265 // following a successful commit. |
232 BlobJournalType blobs_to_remove_; | 266 BlobJournalType blobs_to_remove_; |
233 scoped_refptr<ChainedBlobWriter> chained_blob_writer_; | 267 scoped_refptr<ChainedBlobWriter> chained_blob_writer_; |
| 268 |
| 269 // Set to true between CommitPhaseOne and CommitPhaseTwo/Rollback, to |
| 270 // indicate that the committing_transaction_count_ on the backing store |
| 271 // has been bumped, and journal cleaning should be deferred. |
| 272 bool committing_; |
234 }; | 273 }; |
235 | 274 |
236 class Cursor { | 275 class Cursor { |
237 public: | 276 public: |
238 enum IteratorState { READY = 0, SEEK }; | 277 enum IteratorState { READY = 0, SEEK }; |
239 | 278 |
240 virtual ~Cursor(); | 279 virtual ~Cursor(); |
241 | 280 |
242 struct CursorOptions { | 281 struct CursorOptions { |
243 CursorOptions(); | 282 CursorOptions(); |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
463 int64 database_id, | 502 int64 database_id, |
464 int64 object_store_id, | 503 int64 object_store_id, |
465 int64 index_id, | 504 int64 index_id, |
466 const IndexedDBKey& key, | 505 const IndexedDBKey& key, |
467 scoped_ptr<IndexedDBKey>* found_primary_key, | 506 scoped_ptr<IndexedDBKey>* found_primary_key, |
468 bool* exists) WARN_UNUSED_RESULT; | 507 bool* exists) WARN_UNUSED_RESULT; |
469 | 508 |
470 // Public for IndexedDBActiveBlobRegistry::ReleaseBlobRef. | 509 // Public for IndexedDBActiveBlobRegistry::ReleaseBlobRef. |
471 virtual void ReportBlobUnused(int64 database_id, int64 blob_key); | 510 virtual void ReportBlobUnused(int64 database_id, int64 blob_key); |
472 | 511 |
473 base::FilePath GetBlobFileName(int64 database_id, int64 key); | 512 base::FilePath GetBlobFileName(int64 database_id, int64 key) const; |
474 | 513 |
475 virtual scoped_ptr<Cursor> OpenObjectStoreKeyCursor( | 514 virtual scoped_ptr<Cursor> OpenObjectStoreKeyCursor( |
476 IndexedDBBackingStore::Transaction* transaction, | 515 IndexedDBBackingStore::Transaction* transaction, |
477 int64 database_id, | 516 int64 database_id, |
478 int64 object_store_id, | 517 int64 object_store_id, |
479 const IndexedDBKeyRange& key_range, | 518 const IndexedDBKeyRange& key_range, |
480 blink::WebIDBCursorDirection, | 519 blink::WebIDBCursorDirection, |
481 leveldb::Status*); | 520 leveldb::Status*); |
482 virtual scoped_ptr<Cursor> OpenObjectStoreCursor( | 521 virtual scoped_ptr<Cursor> OpenObjectStoreCursor( |
483 IndexedDBBackingStore::Transaction* transaction, | 522 IndexedDBBackingStore::Transaction* transaction, |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
516 virtual ~IndexedDBBackingStore(); | 555 virtual ~IndexedDBBackingStore(); |
517 | 556 |
518 bool is_incognito() const { return !indexed_db_factory_; } | 557 bool is_incognito() const { return !indexed_db_factory_; } |
519 | 558 |
520 leveldb::Status SetUpMetadata(); | 559 leveldb::Status SetUpMetadata(); |
521 | 560 |
522 virtual bool WriteBlobFile( | 561 virtual bool WriteBlobFile( |
523 int64 database_id, | 562 int64 database_id, |
524 const Transaction::WriteDescriptor& descriptor, | 563 const Transaction::WriteDescriptor& descriptor, |
525 Transaction::ChainedBlobWriter* chained_blob_writer); | 564 Transaction::ChainedBlobWriter* chained_blob_writer); |
526 virtual bool RemoveBlobFile(int64 database_id, int64 key); | 565 |
| 566 // Remove the referenced file on disk. |
| 567 virtual bool RemoveBlobFile(int64 database_id, int64 key) const; |
| 568 |
| 569 // Schedule a call to CleanPrimaryJournalIgnoreReturn() via |
| 570 // an owned timer. If this object is destroyed, the timer |
| 571 // will automatically be cancelled. |
527 virtual void StartJournalCleaningTimer(); | 572 virtual void StartJournalCleaningTimer(); |
| 573 |
| 574 // Attempt to clean the primary journal. This will remove |
| 575 // any referenced files and delete the journal entry. If any |
| 576 // transaction is currently committing this will be deferred |
| 577 // via StartJournalCleaningTimer(). |
528 void CleanPrimaryJournalIgnoreReturn(); | 578 void CleanPrimaryJournalIgnoreReturn(); |
529 | 579 |
530 private: | 580 private: |
531 static scoped_refptr<IndexedDBBackingStore> Create( | 581 static scoped_refptr<IndexedDBBackingStore> Create( |
532 IndexedDBFactory* indexed_db_factory, | 582 IndexedDBFactory* indexed_db_factory, |
533 const GURL& origin_url, | 583 const GURL& origin_url, |
534 const base::FilePath& blob_path, | 584 const base::FilePath& blob_path, |
535 net::URLRequestContext* request_context, | 585 net::URLRequestContext* request_context, |
536 scoped_ptr<LevelDBDatabase> db, | 586 scoped_ptr<LevelDBDatabase> db, |
537 scoped_ptr<LevelDBComparator> comparator, | 587 scoped_ptr<LevelDBComparator> comparator, |
538 base::SequencedTaskRunner* task_runner, | 588 base::SequencedTaskRunner* task_runner, |
539 leveldb::Status* status); | 589 leveldb::Status* status); |
540 | 590 |
541 static bool ReadCorruptionInfo(const base::FilePath& path_base, | 591 static bool ReadCorruptionInfo(const base::FilePath& path_base, |
542 const GURL& origin_url, | 592 const GURL& origin_url, |
543 std::string* message); | 593 std::string* message); |
544 | 594 |
545 leveldb::Status FindKeyInIndex( | 595 leveldb::Status FindKeyInIndex( |
546 IndexedDBBackingStore::Transaction* transaction, | 596 IndexedDBBackingStore::Transaction* transaction, |
547 int64 database_id, | 597 int64 database_id, |
548 int64 object_store_id, | 598 int64 object_store_id, |
549 int64 index_id, | 599 int64 index_id, |
550 const IndexedDBKey& key, | 600 const IndexedDBKey& key, |
551 std::string* found_encoded_primary_key, | 601 std::string* found_encoded_primary_key, |
552 bool* found); | 602 bool* found); |
553 leveldb::Status GetIndexes(int64 database_id, | 603 leveldb::Status GetIndexes(int64 database_id, |
554 int64 object_store_id, | 604 int64 object_store_id, |
555 IndexedDBObjectStoreMetadata::IndexMap* map) | 605 IndexedDBObjectStoreMetadata::IndexMap* map) |
556 WARN_UNUSED_RESULT; | 606 WARN_UNUSED_RESULT; |
557 bool RemoveBlobDirectory(int64 database_id); | 607 |
558 leveldb::Status CleanUpBlobJournal(const std::string& level_db_key); | 608 // Remove the blob directory for the specified database and all contained |
| 609 // blob files. |
| 610 bool RemoveBlobDirectory(int64 database_id) const; |
| 611 |
| 612 // Synchronously read the key-specified blob journal entry from the backing |
| 613 // store, delete all referenced blob files, and erase the journal entry. |
| 614 // This must not be used while temporary entries are present e.g. during |
| 615 // a two-stage transaction commit with blobs. |
| 616 leveldb::Status CleanUpBlobJournal(const std::string& level_db_key) const; |
| 617 |
| 618 // Synchronously delete the files and/or directories on disk referenced by |
| 619 // the blob journal. |
| 620 leveldb::Status CleanUpBlobJournalEntries( |
| 621 const BlobJournalType& journal) const; |
559 | 622 |
560 IndexedDBFactory* indexed_db_factory_; | 623 IndexedDBFactory* indexed_db_factory_; |
561 const GURL origin_url_; | 624 const GURL origin_url_; |
562 base::FilePath blob_path_; | 625 base::FilePath blob_path_; |
563 | 626 |
564 // The origin identifier is a key prefix unique to the origin used in the | 627 // The origin identifier is a key prefix unique to the origin used in the |
565 // leveldb backing store to partition data by origin. It is a normalized | 628 // leveldb backing store to partition data by origin. It is a normalized |
566 // version of the origin URL with a versioning suffix appended, e.g. | 629 // version of the origin URL with a versioning suffix appended, e.g. |
567 // "http_localhost_81@1" Since only one origin is stored per backing store | 630 // "http_localhost_81@1" Since only one origin is stored per backing store |
568 // this is redundant but necessary for backwards compatibility; the suffix | 631 // this is redundant but necessary for backwards compatibility; the suffix |
569 // provides for future flexibility. | 632 // provides for future flexibility. |
570 const std::string origin_identifier_; | 633 const std::string origin_identifier_; |
571 | 634 |
572 net::URLRequestContext* request_context_; | 635 net::URLRequestContext* request_context_; |
573 scoped_refptr<base::SequencedTaskRunner> task_runner_; | 636 scoped_refptr<base::SequencedTaskRunner> task_runner_; |
574 std::set<int> child_process_ids_granted_; | 637 std::set<int> child_process_ids_granted_; |
575 BlobChangeMap incognito_blob_map_; | 638 BlobChangeMap incognito_blob_map_; |
576 base::OneShotTimer<IndexedDBBackingStore> journal_cleaning_timer_; | 639 base::OneShotTimer<IndexedDBBackingStore> journal_cleaning_timer_; |
577 | 640 |
578 scoped_ptr<LevelDBDatabase> db_; | 641 scoped_ptr<LevelDBDatabase> db_; |
579 scoped_ptr<LevelDBComparator> comparator_; | 642 scoped_ptr<LevelDBComparator> comparator_; |
580 // Whenever blobs are registered in active_blob_registry_, indexed_db_factory_ | 643 // Whenever blobs are registered in active_blob_registry_, indexed_db_factory_ |
581 // will hold a reference to this backing store. | 644 // will hold a reference to this backing store. |
582 IndexedDBActiveBlobRegistry active_blob_registry_; | 645 IndexedDBActiveBlobRegistry active_blob_registry_; |
583 base::OneShotTimer<IndexedDBBackingStore> close_timer_; | 646 base::OneShotTimer<IndexedDBBackingStore> close_timer_; |
584 | 647 |
| 648 // Incremented whenever a transaction starts committing, decremented when |
| 649 // complete. While > 0, temporary journal entries may exist so out-of-band |
| 650 // journal cleaning must be deferred. |
| 651 size_t committing_transaction_count_; |
| 652 |
585 DISALLOW_COPY_AND_ASSIGN(IndexedDBBackingStore); | 653 DISALLOW_COPY_AND_ASSIGN(IndexedDBBackingStore); |
586 }; | 654 }; |
587 | 655 |
588 } // namespace content | 656 } // namespace content |
589 | 657 |
590 #endif // CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_BACKING_STORE_H_ | 658 #endif // CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_BACKING_STORE_H_ |
OLD | NEW |