Chromium Code Reviews| 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 #include "content/browser/indexed_db/indexed_db_backing_store.h" | 5 #include "content/browser/indexed_db/indexed_db_backing_store.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
| 11 #include "base/files/file_util.h" | 11 #include "base/files/file_util.h" |
| 12 #include "base/format_macros.h" | 12 #include "base/format_macros.h" |
| 13 #include "base/json/json_reader.h" | 13 #include "base/json/json_reader.h" |
| 14 #include "base/json/json_writer.h" | 14 #include "base/json/json_writer.h" |
| 15 #include "base/logging.h" | 15 #include "base/logging.h" |
| 16 #include "base/macros.h" | 16 #include "base/macros.h" |
| 17 #include "base/memory/ptr_util.h" | |
| 17 #include "base/metrics/histogram.h" | 18 #include "base/metrics/histogram.h" |
| 18 #include "base/strings/string_util.h" | 19 #include "base/strings/string_util.h" |
| 19 #include "base/strings/stringprintf.h" | 20 #include "base/strings/stringprintf.h" |
| 20 #include "base/strings/utf_string_conversions.h" | 21 #include "base/strings/utf_string_conversions.h" |
| 21 #include "base/trace_event/memory_dump_manager.h" | 22 #include "base/trace_event/memory_dump_manager.h" |
| 22 #include "build/build_config.h" | 23 #include "build/build_config.h" |
| 23 #include "content/browser/child_process_security_policy_impl.h" | 24 #include "content/browser/child_process_security_policy_impl.h" |
| 24 #include "content/browser/indexed_db/indexed_db_blob_info.h" | 25 #include "content/browser/indexed_db/indexed_db_blob_info.h" |
| 25 #include "content/browser/indexed_db/indexed_db_class_factory.h" | 26 #include "content/browser/indexed_db/indexed_db_class_factory.h" |
| 26 #include "content/browser/indexed_db/indexed_db_context_impl.h" | 27 #include "content/browser/indexed_db/indexed_db_context_impl.h" |
| (...skipping 736 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 763 active_blob_registry_(this), | 764 active_blob_registry_(this), |
| 764 committing_transaction_count_(0) {} | 765 committing_transaction_count_(0) {} |
| 765 | 766 |
| 766 IndexedDBBackingStore::~IndexedDBBackingStore() { | 767 IndexedDBBackingStore::~IndexedDBBackingStore() { |
| 767 if (!blob_path_.empty() && !child_process_ids_granted_.empty()) { | 768 if (!blob_path_.empty() && !child_process_ids_granted_.empty()) { |
| 768 ChildProcessSecurityPolicyImpl* policy = | 769 ChildProcessSecurityPolicyImpl* policy = |
| 769 ChildProcessSecurityPolicyImpl::GetInstance(); | 770 ChildProcessSecurityPolicyImpl::GetInstance(); |
| 770 for (const auto& pid : child_process_ids_granted_) | 771 for (const auto& pid : child_process_ids_granted_) |
| 771 policy->RevokeAllPermissionsForFile(pid, blob_path_); | 772 policy->RevokeAllPermissionsForFile(pid, blob_path_); |
| 772 } | 773 } |
| 773 base::STLDeleteContainerPairSecondPointers(incognito_blob_map_.begin(), | 774 incognito_blob_map_.clear(); |
| 774 incognito_blob_map_.end()); | |
| 775 // db_'s destructor uses comparator_. The order of destruction is important. | 775 // db_'s destructor uses comparator_. The order of destruction is important. |
| 776 db_.reset(); | 776 db_.reset(); |
| 777 comparator_.reset(); | 777 comparator_.reset(); |
| 778 } | 778 } |
| 779 | 779 |
| 780 IndexedDBBackingStore::RecordIdentifier::RecordIdentifier( | 780 IndexedDBBackingStore::RecordIdentifier::RecordIdentifier( |
| 781 const std::string& primary_key, | 781 const std::string& primary_key, |
| 782 int64_t version) | 782 int64_t version) |
| 783 : primary_key_(primary_key), version_(version) { | 783 : primary_key_(primary_key), version_(version) { |
| 784 DCHECK(!primary_key.empty()); | 784 DCHECK(!primary_key.empty()); |
| (...skipping 1915 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2700 return journal_transaction->Commit(); | 2700 return journal_transaction->Commit(); |
| 2701 } | 2701 } |
| 2702 | 2702 |
| 2703 leveldb::Status IndexedDBBackingStore::Transaction::GetBlobInfoForRecord( | 2703 leveldb::Status IndexedDBBackingStore::Transaction::GetBlobInfoForRecord( |
| 2704 int64_t database_id, | 2704 int64_t database_id, |
| 2705 const std::string& object_store_data_key, | 2705 const std::string& object_store_data_key, |
| 2706 IndexedDBValue* value) { | 2706 IndexedDBValue* value) { |
| 2707 BlobChangeRecord* change_record = NULL; | 2707 BlobChangeRecord* change_record = NULL; |
| 2708 auto blob_iter = blob_change_map_.find(object_store_data_key); | 2708 auto blob_iter = blob_change_map_.find(object_store_data_key); |
| 2709 if (blob_iter != blob_change_map_.end()) { | 2709 if (blob_iter != blob_change_map_.end()) { |
| 2710 change_record = blob_iter->second; | 2710 change_record = blob_iter->second.get(); |
| 2711 } else { | 2711 } else { |
| 2712 blob_iter = incognito_blob_map_.find(object_store_data_key); | 2712 blob_iter = incognito_blob_map_.find(object_store_data_key); |
| 2713 if (blob_iter != incognito_blob_map_.end()) | 2713 if (blob_iter != incognito_blob_map_.end()) |
| 2714 change_record = blob_iter->second; | 2714 change_record = blob_iter->second.get(); |
| 2715 } | 2715 } |
| 2716 if (change_record) { | 2716 if (change_record) { |
| 2717 // Either we haven't written the blob to disk yet or we're in incognito | 2717 // Either we haven't written the blob to disk yet or we're in incognito |
| 2718 // mode, so we have to send back the one they sent us. This change record | 2718 // mode, so we have to send back the one they sent us. This change record |
| 2719 // includes the original UUID. | 2719 // includes the original UUID. |
| 2720 value->blob_info = change_record->blob_info(); | 2720 value->blob_info = change_record->blob_info(); |
| 2721 return leveldb::Status::OK(); | 2721 return leveldb::Status::OK(); |
| 2722 } | 2722 } |
| 2723 | 2723 |
| 2724 BlobEntryKey blob_entry_key; | 2724 BlobEntryKey blob_entry_key; |
| (...skipping 1274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3999 | 3999 |
| 4000 return std::move(cursor); | 4000 return std::move(cursor); |
| 4001 } | 4001 } |
| 4002 | 4002 |
| 4003 IndexedDBBackingStore::Transaction::Transaction( | 4003 IndexedDBBackingStore::Transaction::Transaction( |
| 4004 IndexedDBBackingStore* backing_store) | 4004 IndexedDBBackingStore* backing_store) |
| 4005 : backing_store_(backing_store), database_id_(-1), committing_(false) { | 4005 : backing_store_(backing_store), database_id_(-1), committing_(false) { |
| 4006 } | 4006 } |
| 4007 | 4007 |
| 4008 IndexedDBBackingStore::Transaction::~Transaction() { | 4008 IndexedDBBackingStore::Transaction::~Transaction() { |
| 4009 base::STLDeleteContainerPairSecondPointers(blob_change_map_.begin(), | 4009 blob_change_map_.clear(); |
| 4010 blob_change_map_.end()); | 4010 incognito_blob_map_.clear(); |
| 4011 base::STLDeleteContainerPairSecondPointers(incognito_blob_map_.begin(), | |
| 4012 incognito_blob_map_.end()); | |
| 4013 DCHECK(!committing_); | 4011 DCHECK(!committing_); |
| 4014 } | 4012 } |
| 4015 | 4013 |
| 4016 void IndexedDBBackingStore::Transaction::Begin() { | 4014 void IndexedDBBackingStore::Transaction::Begin() { |
| 4017 IDB_TRACE("IndexedDBBackingStore::Transaction::Begin"); | 4015 IDB_TRACE("IndexedDBBackingStore::Transaction::Begin"); |
| 4018 DCHECK(!transaction_.get()); | 4016 DCHECK(!transaction_.get()); |
| 4019 transaction_ = IndexedDBClassFactory::Get()->CreateLevelDBTransaction( | 4017 transaction_ = IndexedDBClassFactory::Get()->CreateLevelDBTransaction( |
| 4020 backing_store_->db_.get()); | 4018 backing_store_->db_.get()); |
| 4021 | 4019 |
| 4022 // If incognito, this snapshots blobs just as the above transaction_ | 4020 // If incognito, this snapshots blobs just as the above transaction_ |
| 4023 // constructor snapshots the leveldb. | 4021 // constructor snapshots the leveldb. |
| 4024 for (const auto& iter : backing_store_->incognito_blob_map_) | 4022 for (const auto& iter : backing_store_->incognito_blob_map_) |
| 4025 incognito_blob_map_[iter.first] = iter.second->Clone().release(); | 4023 incognito_blob_map_[iter.first] = iter.second->Clone(); |
| 4026 } | 4024 } |
| 4027 | 4025 |
| 4028 static GURL GetURLFromUUID(const string& uuid) { | 4026 static GURL GetURLFromUUID(const string& uuid) { |
| 4029 return GURL("blob:uuid/" + uuid); | 4027 return GURL("blob:uuid/" + uuid); |
| 4030 } | 4028 } |
| 4031 | 4029 |
| 4032 leveldb::Status IndexedDBBackingStore::Transaction::HandleBlobPreTransaction( | 4030 leveldb::Status IndexedDBBackingStore::Transaction::HandleBlobPreTransaction( |
| 4033 BlobEntryKeyValuePairVec* new_blob_entries, | 4031 BlobEntryKeyValuePairVec* new_blob_entries, |
| 4034 WriteDescriptorVec* new_files_to_write) { | 4032 WriteDescriptorVec* new_files_to_write) { |
| 4035 if (backing_store_->is_incognito()) | 4033 if (backing_store_->is_incognito()) |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4240 INTERNAL_WRITE_ERROR(TRANSACTION_COMMIT_METHOD); | 4238 INTERNAL_WRITE_ERROR(TRANSACTION_COMMIT_METHOD); |
| 4241 return s; | 4239 return s; |
| 4242 } | 4240 } |
| 4243 | 4241 |
| 4244 if (backing_store_->is_incognito()) { | 4242 if (backing_store_->is_incognito()) { |
| 4245 if (!blob_change_map_.empty()) { | 4243 if (!blob_change_map_.empty()) { |
| 4246 auto& target_map = backing_store_->incognito_blob_map_; | 4244 auto& target_map = backing_store_->incognito_blob_map_; |
| 4247 for (auto& iter : blob_change_map_) { | 4245 for (auto& iter : blob_change_map_) { |
| 4248 auto target_record = target_map.find(iter.first); | 4246 auto target_record = target_map.find(iter.first); |
| 4249 if (target_record != target_map.end()) { | 4247 if (target_record != target_map.end()) { |
| 4250 delete target_record->second; | |
| 4251 target_map.erase(target_record); | 4248 target_map.erase(target_record); |
| 4252 } | 4249 } |
| 4253 if (iter.second) { | 4250 if (iter.second) { |
| 4254 target_map[iter.first] = iter.second; | 4251 target_map[iter.first] = std::move(iter.second); |
| 4255 iter.second = NULL; | |
| 4256 } | 4252 } |
|
ncarter (slow)
2016/08/15 21:51:33
It seems like this can be further simplified (mayb
Avi (use Gerrit)
2016/08/15 23:46:49
Yes, I'm convinced your rewrite is correct; going
| |
| 4257 } | 4253 } |
| 4258 } | 4254 } |
| 4259 return leveldb::Status::OK(); | 4255 return leveldb::Status::OK(); |
| 4260 } | 4256 } |
| 4261 | 4257 |
| 4262 // Actually delete dead blob files, then remove those entries | 4258 // Actually delete dead blob files, then remove those entries |
| 4263 // from the persisted primary journal. | 4259 // from the persisted primary journal. |
| 4264 if (dead_blobs.empty()) | 4260 if (dead_blobs.empty()) |
| 4265 return leveldb::Status::OK(); | 4261 return leveldb::Status::OK(); |
| 4266 | 4262 |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4425 ScopedVector<storage::BlobDataHandle>* handles) { | 4421 ScopedVector<storage::BlobDataHandle>* handles) { |
| 4426 DCHECK_GT(object_store_data_key.size(), 0UL); | 4422 DCHECK_GT(object_store_data_key.size(), 0UL); |
| 4427 if (database_id_ < 0) | 4423 if (database_id_ < 0) |
| 4428 database_id_ = database_id; | 4424 database_id_ = database_id; |
| 4429 DCHECK_EQ(database_id_, database_id); | 4425 DCHECK_EQ(database_id_, database_id); |
| 4430 | 4426 |
| 4431 const auto& it = blob_change_map_.find(object_store_data_key); | 4427 const auto& it = blob_change_map_.find(object_store_data_key); |
| 4432 BlobChangeRecord* record = NULL; | 4428 BlobChangeRecord* record = NULL; |
| 4433 if (it == blob_change_map_.end()) { | 4429 if (it == blob_change_map_.end()) { |
| 4434 record = new BlobChangeRecord(object_store_data_key, object_store_id); | 4430 record = new BlobChangeRecord(object_store_data_key, object_store_id); |
| 4435 blob_change_map_[object_store_data_key] = record; | 4431 blob_change_map_[object_store_data_key] = base::WrapUnique(record); |
| 4436 } else { | 4432 } else { |
| 4437 record = it->second; | 4433 record = it->second.get(); |
| 4438 } | 4434 } |
| 4439 DCHECK_EQ(record->object_store_id(), object_store_id); | 4435 DCHECK_EQ(record->object_store_id(), object_store_id); |
| 4440 record->SetBlobInfo(blob_info); | 4436 record->SetBlobInfo(blob_info); |
| 4441 record->SetHandles(handles); | 4437 record->SetHandles(handles); |
| 4442 DCHECK(!handles || handles->empty()); | 4438 DCHECK(!handles || handles->empty()); |
| 4443 } | 4439 } |
| 4444 | 4440 |
| 4445 IndexedDBBackingStore::Transaction::WriteDescriptor::WriteDescriptor( | 4441 IndexedDBBackingStore::Transaction::WriteDescriptor::WriteDescriptor( |
| 4446 const GURL& url, | 4442 const GURL& url, |
| 4447 int64_t key, | 4443 int64_t key, |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 4468 | 4464 |
| 4469 IndexedDBBackingStore::Transaction::WriteDescriptor::WriteDescriptor( | 4465 IndexedDBBackingStore::Transaction::WriteDescriptor::WriteDescriptor( |
| 4470 const WriteDescriptor& other) = default; | 4466 const WriteDescriptor& other) = default; |
| 4471 IndexedDBBackingStore::Transaction::WriteDescriptor::~WriteDescriptor() = | 4467 IndexedDBBackingStore::Transaction::WriteDescriptor::~WriteDescriptor() = |
| 4472 default; | 4468 default; |
| 4473 IndexedDBBackingStore::Transaction::WriteDescriptor& | 4469 IndexedDBBackingStore::Transaction::WriteDescriptor& |
| 4474 IndexedDBBackingStore::Transaction::WriteDescriptor:: | 4470 IndexedDBBackingStore::Transaction::WriteDescriptor:: |
| 4475 operator=(const WriteDescriptor& other) = default; | 4471 operator=(const WriteDescriptor& other) = default; |
| 4476 | 4472 |
| 4477 } // namespace content | 4473 } // namespace content |
| OLD | NEW |