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