OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "chrome/browser/sync/syncable/syncable.h" | 5 #include "chrome/browser/sync/syncable/syncable.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <cstring> | 8 #include <cstring> |
9 #include <functional> | 9 #include <functional> |
10 #include <iomanip> | 10 #include <iomanip> |
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
342 SetFieldValues(*this, kernel_info, | 342 SetFieldValues(*this, kernel_info, |
343 &GetBitTempString, &Value::CreateBooleanValue, | 343 &GetBitTempString, &Value::CreateBooleanValue, |
344 BIT_TEMPS_BEGIN, BIT_TEMPS_END - 1); | 344 BIT_TEMPS_BEGIN, BIT_TEMPS_END - 1); |
345 | 345 |
346 return kernel_info; | 346 return kernel_info; |
347 } | 347 } |
348 | 348 |
349 /////////////////////////////////////////////////////////////////////////// | 349 /////////////////////////////////////////////////////////////////////////// |
350 // Directory | 350 // Directory |
351 | 351 |
352 void Directory::InitKernel(const std::string& name, | 352 void Directory::InitKernelForTest( |
353 DirectoryChangeDelegate* delegate) { | 353 const std::string& name, |
354 DCHECK(kernel_ == NULL); | 354 DirectoryChangeDelegate* delegate, |
355 kernel_ = new Kernel(FilePath(), name, KernelLoadInfo(), delegate); | 355 const browser_sync::WeakHandle<TransactionObserver>& |
| 356 transaction_observer) { |
| 357 DCHECK(!kernel_); |
| 358 kernel_ = new Kernel(FilePath(), name, KernelLoadInfo(), |
| 359 delegate, transaction_observer); |
356 } | 360 } |
357 | 361 |
358 Directory::PersistedKernelInfo::PersistedKernelInfo() | 362 Directory::PersistedKernelInfo::PersistedKernelInfo() |
359 : next_id(0) { | 363 : next_id(0) { |
360 for (int i = FIRST_REAL_MODEL_TYPE; i < MODEL_TYPE_COUNT; ++i) { | 364 for (int i = FIRST_REAL_MODEL_TYPE; i < MODEL_TYPE_COUNT; ++i) { |
361 reset_download_progress(ModelTypeFromInt(i)); | 365 reset_download_progress(ModelTypeFromInt(i)); |
362 } | 366 } |
363 } | 367 } |
364 | 368 |
365 Directory::PersistedKernelInfo::~PersistedKernelInfo() {} | 369 Directory::PersistedKernelInfo::~PersistedKernelInfo() {} |
366 | 370 |
367 void Directory::PersistedKernelInfo::reset_download_progress( | 371 void Directory::PersistedKernelInfo::reset_download_progress( |
368 ModelType model_type) { | 372 ModelType model_type) { |
369 download_progress[model_type].set_data_type_id( | 373 download_progress[model_type].set_data_type_id( |
370 GetExtensionFieldNumberFromModelType(model_type)); | 374 GetExtensionFieldNumberFromModelType(model_type)); |
371 // An empty-string token indicates no prior knowledge. | 375 // An empty-string token indicates no prior knowledge. |
372 download_progress[model_type].set_token(std::string()); | 376 download_progress[model_type].set_token(std::string()); |
373 } | 377 } |
374 | 378 |
375 Directory::SaveChangesSnapshot::SaveChangesSnapshot() | 379 Directory::SaveChangesSnapshot::SaveChangesSnapshot() |
376 : kernel_info_status(KERNEL_SHARE_INFO_INVALID) { | 380 : kernel_info_status(KERNEL_SHARE_INFO_INVALID) { |
377 } | 381 } |
378 | 382 |
379 Directory::SaveChangesSnapshot::~SaveChangesSnapshot() {} | 383 Directory::SaveChangesSnapshot::~SaveChangesSnapshot() {} |
380 | 384 |
381 Directory::Kernel::Kernel(const FilePath& db_path, | 385 Directory::Kernel::Kernel( |
382 const string& name, | 386 const FilePath& db_path, const string& name, |
383 const KernelLoadInfo& info, | 387 const KernelLoadInfo& info, DirectoryChangeDelegate* delegate, |
384 DirectoryChangeDelegate* delegate) | 388 const browser_sync::WeakHandle<TransactionObserver>& |
| 389 transaction_observer) |
385 : db_path(db_path), | 390 : db_path(db_path), |
386 refcount(1), | 391 refcount(1), |
387 next_write_transaction_id(0), | 392 next_write_transaction_id(0), |
388 name(name), | 393 name(name), |
389 metahandles_index(new Directory::MetahandlesIndex), | 394 metahandles_index(new Directory::MetahandlesIndex), |
390 ids_index(new Directory::IdsIndex), | 395 ids_index(new Directory::IdsIndex), |
391 parent_id_child_index(new Directory::ParentIdChildIndex), | 396 parent_id_child_index(new Directory::ParentIdChildIndex), |
392 client_tag_index(new Directory::ClientTagIndex), | 397 client_tag_index(new Directory::ClientTagIndex), |
393 unapplied_update_metahandles(new MetahandleSet), | 398 unapplied_update_metahandles(new MetahandleSet), |
394 unsynced_metahandles(new MetahandleSet), | 399 unsynced_metahandles(new MetahandleSet), |
395 dirty_metahandles(new MetahandleSet), | 400 dirty_metahandles(new MetahandleSet), |
396 metahandles_to_purge(new MetahandleSet), | 401 metahandles_to_purge(new MetahandleSet), |
397 info_status(Directory::KERNEL_SHARE_INFO_VALID), | 402 info_status(Directory::KERNEL_SHARE_INFO_VALID), |
398 persisted_info(info.kernel_info), | 403 persisted_info(info.kernel_info), |
399 cache_guid(info.cache_guid), | 404 cache_guid(info.cache_guid), |
400 next_metahandle(info.max_metahandle + 1), | 405 next_metahandle(info.max_metahandle + 1), |
401 delegate(delegate), | 406 delegate(delegate), |
402 observers(new ObserverListThreadSafe<TransactionObserver>()) { | 407 transaction_observer(transaction_observer) { |
403 DCHECK(delegate); | 408 DCHECK(delegate); |
| 409 DCHECK(transaction_observer.IsInitialized()); |
404 } | 410 } |
405 | 411 |
406 void Directory::Kernel::AddRef() { | 412 void Directory::Kernel::AddRef() { |
407 base::subtle::NoBarrier_AtomicIncrement(&refcount, 1); | 413 base::subtle::NoBarrier_AtomicIncrement(&refcount, 1); |
408 } | 414 } |
409 | 415 |
410 void Directory::Kernel::Release() { | 416 void Directory::Kernel::Release() { |
411 if (!base::subtle::NoBarrier_AtomicIncrement(&refcount, -1)) | 417 if (!base::subtle::NoBarrier_AtomicIncrement(&refcount, -1)) |
412 delete this; | 418 delete this; |
413 } | 419 } |
(...skipping 11 matching lines...) Expand all Loading... |
425 delete metahandles_index; | 431 delete metahandles_index; |
426 } | 432 } |
427 | 433 |
428 Directory::Directory() : kernel_(NULL), store_(NULL) { | 434 Directory::Directory() : kernel_(NULL), store_(NULL) { |
429 } | 435 } |
430 | 436 |
431 Directory::~Directory() { | 437 Directory::~Directory() { |
432 Close(); | 438 Close(); |
433 } | 439 } |
434 | 440 |
435 DirOpenResult Directory::Open(const FilePath& file_path, const string& name, | 441 DirOpenResult Directory::Open( |
436 DirectoryChangeDelegate* delegate) { | 442 const FilePath& file_path, const string& name, |
437 const DirOpenResult result = OpenImpl(file_path, name, delegate); | 443 DirectoryChangeDelegate* delegate, |
| 444 const browser_sync::WeakHandle<TransactionObserver>& |
| 445 transaction_observer) { |
| 446 const DirOpenResult result = |
| 447 OpenImpl(file_path, name, delegate, transaction_observer); |
438 if (OPENED != result) | 448 if (OPENED != result) |
439 Close(); | 449 Close(); |
440 return result; | 450 return result; |
441 } | 451 } |
442 | 452 |
443 void Directory::InitializeIndices() { | 453 void Directory::InitializeIndices() { |
444 MetahandlesIndex::iterator it = kernel_->metahandles_index->begin(); | 454 MetahandlesIndex::iterator it = kernel_->metahandles_index->begin(); |
445 for (; it != kernel_->metahandles_index->end(); ++it) { | 455 for (; it != kernel_->metahandles_index->end(); ++it) { |
446 EntryKernel* entry = *it; | 456 EntryKernel* entry = *it; |
447 InitializeIndexEntry<ParentIdAndHandleIndexer>(entry, | 457 InitializeIndexEntry<ParentIdAndHandleIndexer>(entry, |
448 kernel_->parent_id_child_index); | 458 kernel_->parent_id_child_index); |
449 InitializeIndexEntry<IdIndexer>(entry, kernel_->ids_index); | 459 InitializeIndexEntry<IdIndexer>(entry, kernel_->ids_index); |
450 InitializeIndexEntry<ClientTagIndexer>(entry, kernel_->client_tag_index); | 460 InitializeIndexEntry<ClientTagIndexer>(entry, kernel_->client_tag_index); |
451 if (entry->ref(IS_UNSYNCED)) | 461 if (entry->ref(IS_UNSYNCED)) |
452 kernel_->unsynced_metahandles->insert(entry->ref(META_HANDLE)); | 462 kernel_->unsynced_metahandles->insert(entry->ref(META_HANDLE)); |
453 if (entry->ref(IS_UNAPPLIED_UPDATE)) | 463 if (entry->ref(IS_UNAPPLIED_UPDATE)) |
454 kernel_->unapplied_update_metahandles->insert(entry->ref(META_HANDLE)); | 464 kernel_->unapplied_update_metahandles->insert(entry->ref(META_HANDLE)); |
455 DCHECK(!entry->is_dirty()); | 465 DCHECK(!entry->is_dirty()); |
456 } | 466 } |
457 } | 467 } |
458 | 468 |
459 DirectoryBackingStore* Directory::CreateBackingStore( | 469 DirectoryBackingStore* Directory::CreateBackingStore( |
460 const string& dir_name, const FilePath& backing_filepath) { | 470 const string& dir_name, const FilePath& backing_filepath) { |
461 return new DirectoryBackingStore(dir_name, backing_filepath); | 471 return new DirectoryBackingStore(dir_name, backing_filepath); |
462 } | 472 } |
463 | 473 |
464 DirOpenResult Directory::OpenImpl(const FilePath& file_path, | 474 DirOpenResult Directory::OpenImpl( |
465 const string& name, | 475 const FilePath& file_path, |
466 DirectoryChangeDelegate* delegate) { | 476 const string& name, |
| 477 DirectoryChangeDelegate* delegate, |
| 478 const browser_sync::WeakHandle<TransactionObserver>& |
| 479 transaction_observer) { |
467 DCHECK_EQ(static_cast<DirectoryBackingStore*>(NULL), store_); | 480 DCHECK_EQ(static_cast<DirectoryBackingStore*>(NULL), store_); |
468 FilePath db_path(file_path); | 481 FilePath db_path(file_path); |
469 file_util::AbsolutePath(&db_path); | 482 file_util::AbsolutePath(&db_path); |
470 store_ = CreateBackingStore(name, db_path); | 483 store_ = CreateBackingStore(name, db_path); |
471 | 484 |
472 KernelLoadInfo info; | 485 KernelLoadInfo info; |
473 // Temporary indices before kernel_ initialized in case Load fails. We 0(1) | 486 // Temporary indices before kernel_ initialized in case Load fails. We 0(1) |
474 // swap these later. | 487 // swap these later. |
475 MetahandlesIndex metas_bucket; | 488 MetahandlesIndex metas_bucket; |
476 DirOpenResult result = store_->Load(&metas_bucket, &info); | 489 DirOpenResult result = store_->Load(&metas_bucket, &info); |
477 if (OPENED != result) | 490 if (OPENED != result) |
478 return result; | 491 return result; |
479 | 492 |
480 kernel_ = new Kernel(db_path, name, info, delegate); | 493 kernel_ = new Kernel(db_path, name, info, delegate, transaction_observer); |
481 kernel_->metahandles_index->swap(metas_bucket); | 494 kernel_->metahandles_index->swap(metas_bucket); |
482 InitializeIndices(); | 495 InitializeIndices(); |
483 return OPENED; | 496 return OPENED; |
484 } | 497 } |
485 | 498 |
486 void Directory::Close() { | 499 void Directory::Close() { |
487 if (store_) | 500 if (store_) |
488 delete store_; | 501 delete store_; |
489 store_ = NULL; | 502 store_ = NULL; |
490 if (kernel_) { | 503 if (kernel_) { |
(...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1102 int64 elapsed_ms = check_timer.Elapsed().InMilliseconds(); | 1115 int64 elapsed_ms = check_timer.Elapsed().InMilliseconds(); |
1103 if (elapsed_ms > max_ms) { | 1116 if (elapsed_ms > max_ms) { |
1104 VLOG(1) << "Cutting Invariant check short after " << elapsed_ms | 1117 VLOG(1) << "Cutting Invariant check short after " << elapsed_ms |
1105 << "ms. Processed " << entries_done << "/" << handles.size() | 1118 << "ms. Processed " << entries_done << "/" << handles.size() |
1106 << " entries"; | 1119 << " entries"; |
1107 return; | 1120 return; |
1108 } | 1121 } |
1109 } | 1122 } |
1110 } | 1123 } |
1111 | 1124 |
1112 void Directory::AddTransactionObserver(TransactionObserver* observer) { | |
1113 kernel_->observers->AddObserver(observer); | |
1114 } | |
1115 | |
1116 void Directory::RemoveTransactionObserver(TransactionObserver* observer) { | |
1117 kernel_->observers->RemoveObserver(observer); | |
1118 } | |
1119 | |
1120 /////////////////////////////////////////////////////////////////////////////// | 1125 /////////////////////////////////////////////////////////////////////////////// |
1121 // ScopedKernelLock | 1126 // ScopedKernelLock |
1122 | 1127 |
1123 ScopedKernelLock::ScopedKernelLock(const Directory* dir) | 1128 ScopedKernelLock::ScopedKernelLock(const Directory* dir) |
1124 : scoped_lock_(dir->kernel_->mutex), dir_(const_cast<Directory*>(dir)) { | 1129 : scoped_lock_(dir->kernel_->mutex), dir_(const_cast<Directory*>(dir)) { |
1125 } | 1130 } |
1126 | 1131 |
1127 /////////////////////////////////////////////////////////////////////////// | 1132 /////////////////////////////////////////////////////////////////////////// |
1128 // Transactions | 1133 // Transactions |
1129 | 1134 |
(...skipping 16 matching lines...) Expand all Loading... |
1146 << name_ << " transaction completed in " << elapsed.InSecondsF() | 1151 << name_ << " transaction completed in " << elapsed.InSecondsF() |
1147 << " seconds."; | 1152 << " seconds."; |
1148 } | 1153 } |
1149 | 1154 |
1150 BaseTransaction::BaseTransaction(const tracked_objects::Location& from_here, | 1155 BaseTransaction::BaseTransaction(const tracked_objects::Location& from_here, |
1151 const char* name, | 1156 const char* name, |
1152 WriterTag writer, | 1157 WriterTag writer, |
1153 Directory* directory) | 1158 Directory* directory) |
1154 : from_here_(from_here), name_(name), writer_(writer), | 1159 : from_here_(from_here), name_(name), writer_(writer), |
1155 directory_(directory), dirkernel_(directory->kernel_) { | 1160 directory_(directory), dirkernel_(directory->kernel_) { |
1156 dirkernel_->observers->Notify( | 1161 dirkernel_->transaction_observer.Call(FROM_HERE, |
1157 &TransactionObserver::OnTransactionStart, from_here_, writer_); | 1162 &TransactionObserver::OnTransactionStart, from_here_, writer_); |
1158 } | 1163 } |
1159 | 1164 |
1160 BaseTransaction::~BaseTransaction() { | 1165 BaseTransaction::~BaseTransaction() { |
1161 if (writer_ != INVALID) { | 1166 if (writer_ != INVALID) { |
1162 dirkernel_->observers->Notify( | 1167 dirkernel_->transaction_observer.Call(FROM_HERE, |
1163 &TransactionObserver::OnTransactionEnd, from_here_, writer_); | 1168 &TransactionObserver::OnTransactionEnd, from_here_, writer_); |
1164 } | 1169 } |
1165 } | 1170 } |
1166 | 1171 |
1167 ReadTransaction::ReadTransaction(const tracked_objects::Location& location, | 1172 ReadTransaction::ReadTransaction(const tracked_objects::Location& location, |
1168 Directory* directory) | 1173 Directory* directory) |
1169 : BaseTransaction(location, "Read", INVALID, directory) { | 1174 : BaseTransaction(location, "Read", INVALID, directory) { |
1170 Lock(); | 1175 Lock(); |
1171 } | 1176 } |
1172 | 1177 |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1261 immutable_write_transaction_info, this); | 1266 immutable_write_transaction_info, this); |
1262 } else { | 1267 } else { |
1263 delegate->HandleCalculateChangesChangeEventFromSyncer( | 1268 delegate->HandleCalculateChangesChangeEventFromSyncer( |
1264 immutable_write_transaction_info, this); | 1269 immutable_write_transaction_info, this); |
1265 } | 1270 } |
1266 | 1271 |
1267 ModelTypeBitSet models_with_changes = | 1272 ModelTypeBitSet models_with_changes = |
1268 delegate->HandleTransactionEndingChangeEvent( | 1273 delegate->HandleTransactionEndingChangeEvent( |
1269 immutable_write_transaction_info, this); | 1274 immutable_write_transaction_info, this); |
1270 | 1275 |
1271 dirkernel_->observers->Notify( | 1276 dirkernel_->transaction_observer.Call(FROM_HERE, |
1272 &TransactionObserver::OnTransactionWrite, | 1277 &TransactionObserver::OnTransactionWrite, |
1273 immutable_write_transaction_info, models_with_changes); | 1278 immutable_write_transaction_info, models_with_changes); |
1274 | 1279 |
1275 return models_with_changes; | 1280 return models_with_changes; |
1276 } | 1281 } |
1277 | 1282 |
1278 void WriteTransaction::NotifyTransactionComplete( | 1283 void WriteTransaction::NotifyTransactionComplete( |
1279 ModelTypeBitSet models_with_changes) { | 1284 ModelTypeBitSet models_with_changes) { |
1280 dirkernel_->delegate->HandleTransactionCompleteChangeEvent( | 1285 dirkernel_->delegate->HandleTransactionCompleteChangeEvent( |
1281 models_with_changes); | 1286 models_with_changes); |
(...skipping 739 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2021 if (entry->ref(NEXT_ID).IsRoot() || | 2026 if (entry->ref(NEXT_ID).IsRoot() || |
2022 entry->ref(NEXT_ID) != entry->ref(PREV_ID)) { | 2027 entry->ref(NEXT_ID) != entry->ref(PREV_ID)) { |
2023 return entry; | 2028 return entry; |
2024 } | 2029 } |
2025 } | 2030 } |
2026 // There were no children in the linked list. | 2031 // There were no children in the linked list. |
2027 return NULL; | 2032 return NULL; |
2028 } | 2033 } |
2029 | 2034 |
2030 } // namespace syncable | 2035 } // namespace syncable |
OLD | NEW |