| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 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 "sync/syncable/directory.h" | 5 #include "sync/syncable/directory.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <iterator> | 8 #include <iterator> |
| 9 | 9 |
| 10 #include "base/base64.h" | 10 #include "base/base64.h" |
| 11 #include "base/guid.h" |
| 11 #include "base/metrics/histogram.h" | 12 #include "base/metrics/histogram.h" |
| 12 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
| 13 #include "base/strings/string_number_conversions.h" | 14 #include "base/strings/string_number_conversions.h" |
| 14 #include "base/trace_event/trace_event.h" | 15 #include "base/trace_event/trace_event.h" |
| 15 #include "sync/internal_api/public/base/attachment_id_proto.h" | 16 #include "sync/internal_api/public/base/attachment_id_proto.h" |
| 16 #include "sync/internal_api/public/base/unique_position.h" | 17 #include "sync/internal_api/public/base/unique_position.h" |
| 17 #include "sync/internal_api/public/util/unrecoverable_error_handler.h" | 18 #include "sync/internal_api/public/util/unrecoverable_error_handler.h" |
| 18 #include "sync/syncable/entry.h" | 19 #include "sync/syncable/entry.h" |
| 19 #include "sync/syncable/entry_kernel.h" | 20 #include "sync/syncable/entry_kernel.h" |
| 20 #include "sync/syncable/in_memory_directory_backing_store.h" | 21 #include "sync/syncable/in_memory_directory_backing_store.h" |
| 21 #include "sync/syncable/on_disk_directory_backing_store.h" | 22 #include "sync/syncable/on_disk_directory_backing_store.h" |
| 22 #include "sync/syncable/scoped_kernel_lock.h" | 23 #include "sync/syncable/scoped_kernel_lock.h" |
| 23 #include "sync/syncable/scoped_parent_child_index_updater.h" | 24 #include "sync/syncable/scoped_parent_child_index_updater.h" |
| 24 #include "sync/syncable/syncable-inl.h" | 25 #include "sync/syncable/syncable-inl.h" |
| 25 #include "sync/syncable/syncable_base_transaction.h" | 26 #include "sync/syncable/syncable_base_transaction.h" |
| 26 #include "sync/syncable/syncable_changes_version.h" | 27 #include "sync/syncable/syncable_changes_version.h" |
| 27 #include "sync/syncable/syncable_read_transaction.h" | 28 #include "sync/syncable/syncable_read_transaction.h" |
| 28 #include "sync/syncable/syncable_util.h" | 29 #include "sync/syncable/syncable_util.h" |
| 29 #include "sync/syncable/syncable_write_transaction.h" | 30 #include "sync/syncable/syncable_write_transaction.h" |
| 30 | 31 |
| 31 using std::string; | 32 using std::string; |
| 32 | 33 |
| 33 namespace syncer { | 34 namespace syncer { |
| 34 namespace syncable { | 35 namespace syncable { |
| 35 | 36 |
| 36 // static | 37 // static |
| 37 const base::FilePath::CharType Directory::kSyncDatabaseFilename[] = | 38 const base::FilePath::CharType Directory::kSyncDatabaseFilename[] = |
| 38 FILE_PATH_LITERAL("SyncData.sqlite3"); | 39 FILE_PATH_LITERAL("SyncData.sqlite3"); |
| 39 | 40 |
| 40 Directory::PersistedKernelInfo::PersistedKernelInfo() | 41 Directory::PersistedKernelInfo::PersistedKernelInfo() { |
| 41 : next_id(0) { | |
| 42 ModelTypeSet protocol_types = ProtocolTypes(); | 42 ModelTypeSet protocol_types = ProtocolTypes(); |
| 43 for (ModelTypeSet::Iterator iter = protocol_types.First(); iter.Good(); | 43 for (ModelTypeSet::Iterator iter = protocol_types.First(); iter.Good(); |
| 44 iter.Inc()) { | 44 iter.Inc()) { |
| 45 ResetDownloadProgress(iter.Get()); | 45 ResetDownloadProgress(iter.Get()); |
| 46 transaction_version[iter.Get()] = 0; | 46 transaction_version[iter.Get()] = 0; |
| 47 } | 47 } |
| 48 } | 48 } |
| 49 | 49 |
| 50 Directory::PersistedKernelInfo::~PersistedKernelInfo() {} | 50 Directory::PersistedKernelInfo::~PersistedKernelInfo() {} |
| 51 | 51 |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 190 JournalIndex delete_journals; | 190 JournalIndex delete_journals; |
| 191 MetahandleSet metahandles_to_purge; | 191 MetahandleSet metahandles_to_purge; |
| 192 | 192 |
| 193 DirOpenResult result = store_->Load(&tmp_handles_map, &delete_journals, | 193 DirOpenResult result = store_->Load(&tmp_handles_map, &delete_journals, |
| 194 &metahandles_to_purge, &info); | 194 &metahandles_to_purge, &info); |
| 195 if (OPENED != result) | 195 if (OPENED != result) |
| 196 return result; | 196 return result; |
| 197 | 197 |
| 198 DCHECK(!kernel_); | 198 DCHECK(!kernel_); |
| 199 kernel_ = new Kernel(name, info, delegate, transaction_observer); | 199 kernel_ = new Kernel(name, info, delegate, transaction_observer); |
| 200 kernel_->metahandles_to_purge.swap(metahandles_to_purge); |
| 200 delete_journal_.reset(new DeleteJournal(&delete_journals)); | 201 delete_journal_.reset(new DeleteJournal(&delete_journals)); |
| 201 InitializeIndices(&tmp_handles_map); | 202 InitializeIndices(&tmp_handles_map); |
| 202 | 203 |
| 203 // Write back the share info to reserve some space in 'next_id'. This will | 204 // Save changes back in case there are any metahandles to purge. |
| 204 // prevent local ID reuse in the case of an early crash. See the comments in | |
| 205 // TakeSnapshotForSaveChanges() or crbug.com/142987 for more information. | |
| 206 kernel_->info_status = KERNEL_SHARE_INFO_DIRTY; | |
| 207 | |
| 208 kernel_->metahandles_to_purge.swap(metahandles_to_purge); | |
| 209 if (!SaveChanges()) | 205 if (!SaveChanges()) |
| 210 return FAILED_INITIAL_WRITE; | 206 return FAILED_INITIAL_WRITE; |
| 211 | 207 |
| 212 // Now that we've successfully opened the store, install an error handler to | 208 // Now that we've successfully opened the store, install an error handler to |
| 213 // deal with catastrophic errors that may occur later on. Use a weak pointer | 209 // deal with catastrophic errors that may occur later on. Use a weak pointer |
| 214 // because we cannot guarantee that this Directory will outlive the Closure. | 210 // because we cannot guarantee that this Directory will outlive the Closure. |
| 215 store_->SetCatastrophicErrorHandler(base::Bind( | 211 store_->SetCatastrophicErrorHandler(base::Bind( |
| 216 &Directory::OnCatastrophicError, weak_ptr_factory_.GetWeakPtr())); | 212 &Directory::OnCatastrophicError, weak_ptr_factory_.GetWeakPtr())); |
| 217 | 213 |
| 218 return OPENED; | 214 return OPENED; |
| (...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 568 entry->clear_dirty(NULL); | 564 entry->clear_dirty(NULL); |
| 569 } | 565 } |
| 570 ClearDirtyMetahandles(lock); | 566 ClearDirtyMetahandles(lock); |
| 571 | 567 |
| 572 // Set purged handles. | 568 // Set purged handles. |
| 573 DCHECK(snapshot->metahandles_to_purge.empty()); | 569 DCHECK(snapshot->metahandles_to_purge.empty()); |
| 574 snapshot->metahandles_to_purge.swap(kernel_->metahandles_to_purge); | 570 snapshot->metahandles_to_purge.swap(kernel_->metahandles_to_purge); |
| 575 | 571 |
| 576 // Fill kernel_info_status and kernel_info. | 572 // Fill kernel_info_status and kernel_info. |
| 577 snapshot->kernel_info = kernel_->persisted_info; | 573 snapshot->kernel_info = kernel_->persisted_info; |
| 578 // To avoid duplicates when the process crashes, we record the next_id to be | |
| 579 // greater magnitude than could possibly be reached before the next save | |
| 580 // changes. In other words, it's effectively impossible for the user to | |
| 581 // generate 65536 new bookmarks in 3 seconds. | |
| 582 snapshot->kernel_info.next_id -= 65536; | |
| 583 snapshot->kernel_info_status = kernel_->info_status; | 574 snapshot->kernel_info_status = kernel_->info_status; |
| 584 // This one we reset on failure. | 575 // This one we reset on failure. |
| 585 kernel_->info_status = KERNEL_SHARE_INFO_VALID; | 576 kernel_->info_status = KERNEL_SHARE_INFO_VALID; |
| 586 | 577 |
| 587 delete_journal_->TakeSnapshotAndClear( | 578 delete_journal_->TakeSnapshotAndClear( |
| 588 &trans, &snapshot->delete_journals, &snapshot->delete_journals_to_purge); | 579 &trans, &snapshot->delete_journals, &snapshot->delete_journals_to_purge); |
| 589 } | 580 } |
| 590 | 581 |
| 591 bool Directory::SaveChanges() { | 582 bool Directory::SaveChanges() { |
| 592 bool success = false; | 583 bool success = false; |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 948 } | 939 } |
| 949 | 940 |
| 950 int64 Directory::GetTransactionVersion(ModelType type) const { | 941 int64 Directory::GetTransactionVersion(ModelType type) const { |
| 951 kernel_->transaction_mutex.AssertAcquired(); | 942 kernel_->transaction_mutex.AssertAcquired(); |
| 952 return kernel_->persisted_info.transaction_version[type]; | 943 return kernel_->persisted_info.transaction_version[type]; |
| 953 } | 944 } |
| 954 | 945 |
| 955 void Directory::IncrementTransactionVersion(ModelType type) { | 946 void Directory::IncrementTransactionVersion(ModelType type) { |
| 956 kernel_->transaction_mutex.AssertAcquired(); | 947 kernel_->transaction_mutex.AssertAcquired(); |
| 957 kernel_->persisted_info.transaction_version[type]++; | 948 kernel_->persisted_info.transaction_version[type]++; |
| 949 kernel_->info_status = KERNEL_SHARE_INFO_DIRTY; |
| 958 } | 950 } |
| 959 | 951 |
| 960 void Directory::GetDataTypeContext(BaseTransaction* trans, | 952 void Directory::GetDataTypeContext(BaseTransaction* trans, |
| 961 ModelType type, | 953 ModelType type, |
| 962 sync_pb::DataTypeContext* context) const { | 954 sync_pb::DataTypeContext* context) const { |
| 963 ScopedKernelLock lock(this); | 955 ScopedKernelLock lock(this); |
| 964 context->CopyFrom(kernel_->persisted_info.datatype_context[type]); | 956 context->CopyFrom(kernel_->persisted_info.datatype_context[type]); |
| 965 } | 957 } |
| 966 | 958 |
| 967 void Directory::SetDataTypeContext( | 959 void Directory::SetDataTypeContext( |
| (...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1332 void Directory::SetInvariantCheckLevel(InvariantCheckLevel check_level) { | 1324 void Directory::SetInvariantCheckLevel(InvariantCheckLevel check_level) { |
| 1333 invariant_check_level_ = check_level; | 1325 invariant_check_level_ = check_level; |
| 1334 } | 1326 } |
| 1335 | 1327 |
| 1336 int64 Directory::NextMetahandle() { | 1328 int64 Directory::NextMetahandle() { |
| 1337 ScopedKernelLock lock(this); | 1329 ScopedKernelLock lock(this); |
| 1338 int64 metahandle = (kernel_->next_metahandle)++; | 1330 int64 metahandle = (kernel_->next_metahandle)++; |
| 1339 return metahandle; | 1331 return metahandle; |
| 1340 } | 1332 } |
| 1341 | 1333 |
| 1342 // Always returns a client ID that is the string representation of a negative | 1334 // Generates next client ID based on a randomly generated GUID. |
| 1343 // number. | |
| 1344 Id Directory::NextId() { | 1335 Id Directory::NextId() { |
| 1345 int64 result; | 1336 return Id::CreateFromClientString(base::GenerateGUID()); |
| 1346 { | |
| 1347 ScopedKernelLock lock(this); | |
| 1348 result = (kernel_->persisted_info.next_id)--; | |
| 1349 kernel_->info_status = KERNEL_SHARE_INFO_DIRTY; | |
| 1350 } | |
| 1351 DCHECK_LT(result, 0); | |
| 1352 return Id::CreateFromClientString(base::Int64ToString(result)); | |
| 1353 } | 1337 } |
| 1354 | 1338 |
| 1355 bool Directory::HasChildren(BaseTransaction* trans, const Id& id) { | 1339 bool Directory::HasChildren(BaseTransaction* trans, const Id& id) { |
| 1356 ScopedKernelLock lock(this); | 1340 ScopedKernelLock lock(this); |
| 1357 return kernel_->parent_child_index.GetChildren(id) != NULL; | 1341 return kernel_->parent_child_index.GetChildren(id) != NULL; |
| 1358 } | 1342 } |
| 1359 | 1343 |
| 1360 Id Directory::GetFirstChildId(BaseTransaction* trans, | 1344 Id Directory::GetFirstChildId(BaseTransaction* trans, |
| 1361 const EntryKernel* parent) { | 1345 const EntryKernel* parent) { |
| 1362 DCHECK(parent); | 1346 DCHECK(parent); |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1571 Directory::Kernel* Directory::kernel() { | 1555 Directory::Kernel* Directory::kernel() { |
| 1572 return kernel_; | 1556 return kernel_; |
| 1573 } | 1557 } |
| 1574 | 1558 |
| 1575 const Directory::Kernel* Directory::kernel() const { | 1559 const Directory::Kernel* Directory::kernel() const { |
| 1576 return kernel_; | 1560 return kernel_; |
| 1577 } | 1561 } |
| 1578 | 1562 |
| 1579 } // namespace syncable | 1563 } // namespace syncable |
| 1580 } // namespace syncer | 1564 } // namespace syncer |
| OLD | NEW |