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 |