| 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 #ifndef SYNC_SYNCABLE_DIRECTORY_H_ | 5 #ifndef SYNC_SYNCABLE_DIRECTORY_H_ |
| 6 #define SYNC_SYNCABLE_DIRECTORY_H_ | 6 #define SYNC_SYNCABLE_DIRECTORY_H_ |
| 7 | 7 |
| 8 #include <deque> | 8 #include <deque> |
| 9 #include <set> | 9 #include <set> |
| 10 #include <string> | 10 #include <string> |
| 11 #include <vector> | 11 #include <vector> |
| 12 | 12 |
| 13 #include "base/basictypes.h" | 13 #include "base/basictypes.h" |
| 14 #include "base/containers/hash_tables.h" | 14 #include "base/containers/hash_tables.h" |
| 15 #include "base/file_util.h" | 15 #include "base/file_util.h" |
| 16 #include "base/gtest_prod_util.h" | 16 #include "base/gtest_prod_util.h" |
| 17 #include "base/values.h" | 17 #include "base/values.h" |
| 18 #include "sync/base/sync_export.h" | 18 #include "sync/base/sync_export.h" |
| 19 #include "sync/internal_api/public/util/report_unrecoverable_error_function.h" | 19 #include "sync/internal_api/public/util/report_unrecoverable_error_function.h" |
| 20 #include "sync/internal_api/public/util/weak_handle.h" | 20 #include "sync/internal_api/public/util/weak_handle.h" |
| 21 #include "sync/syncable/dir_open_result.h" | 21 #include "sync/syncable/dir_open_result.h" |
| 22 #include "sync/syncable/entry_kernel.h" | 22 #include "sync/syncable/entry_kernel.h" |
| 23 #include "sync/syncable/metahandle_set.h" | 23 #include "sync/syncable/metahandle_set.h" |
| 24 #include "sync/syncable/parent_child_index.h" | 24 #include "sync/syncable/parent_child_index.h" |
| 25 #include "sync/syncable/syncable_delete_journal.h" | 25 #include "sync/syncable/syncable_delete_journal.h" |
| 26 | 26 |
| 27 namespace syncer { | 27 namespace syncer { |
| 28 | 28 |
| 29 class AttachmentId; |
| 29 class Cryptographer; | 30 class Cryptographer; |
| 30 class TestUserShare; | 31 class TestUserShare; |
| 31 class UnrecoverableErrorHandler; | 32 class UnrecoverableErrorHandler; |
| 32 | 33 |
| 33 namespace syncable { | 34 namespace syncable { |
| 34 | 35 |
| 35 class BaseTransaction; | 36 class BaseTransaction; |
| 36 class BaseWriteTransaction; | 37 class BaseWriteTransaction; |
| 37 class DirectoryChangeDelegate; | 38 class DirectoryChangeDelegate; |
| 38 class DirectoryBackingStore; | 39 class DirectoryBackingStore; |
| 39 class NigoriHandler; | 40 class NigoriHandler; |
| 40 class ScopedKernelLock; | 41 class ScopedKernelLock; |
| 41 class TransactionObserver; | 42 class TransactionObserver; |
| 42 class WriteTransaction; | 43 class WriteTransaction; |
| 43 | 44 |
| 44 enum InvariantCheckLevel { | 45 enum InvariantCheckLevel { |
| 45 OFF = 0, // No checking. | 46 OFF = 0, // No checking. |
| 46 VERIFY_CHANGES = 1, // Checks only mutated entries. Does not check hierarchy. | 47 VERIFY_CHANGES = 1, // Checks only mutated entries. Does not check hierarchy. |
| 47 FULL_DB_VERIFICATION = 2 // Check every entry. This can be expensive. | 48 FULL_DB_VERIFICATION = 2 // Check every entry. This can be expensive. |
| 48 }; | 49 }; |
| 49 | 50 |
| 51 // Directory stores and manages EntryKernels. |
| 52 // |
| 53 // This class is tightly coupled to several other classes (see friends). |
| 50 class SYNC_EXPORT Directory { | 54 class SYNC_EXPORT Directory { |
| 51 friend class BaseTransaction; | 55 friend class BaseTransaction; |
| 52 friend class Entry; | 56 friend class Entry; |
| 53 friend class ModelNeutralMutableEntry; | 57 friend class ModelNeutralMutableEntry; |
| 54 friend class MutableEntry; | 58 friend class MutableEntry; |
| 55 friend class ReadTransaction; | 59 friend class ReadTransaction; |
| 56 friend class ScopedKernelLock; | 60 friend class ScopedKernelLock; |
| 57 friend class WriteTransaction; | 61 friend class WriteTransaction; |
| 58 friend class SyncableDirectoryTest; | 62 friend class SyncableDirectoryTest; |
| 59 friend class syncer::TestUserShare; | 63 friend class syncer::TestUserShare; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 73 // | 77 // |
| 74 // It gets worse, though. The Anroid STL library has a bug that means it may | 78 // It gets worse, though. The Anroid STL library has a bug that means it may |
| 75 // invalidate all iterators when you erase from the map, too. That means that | 79 // invalidate all iterators when you erase from the map, too. That means that |
| 76 // you can't iterate while erasing. STLDeleteElements(), std::remove_if(), | 80 // you can't iterate while erasing. STLDeleteElements(), std::remove_if(), |
| 77 // and other similar functions are off-limits too, until this bug is fixed. | 81 // and other similar functions are off-limits too, until this bug is fixed. |
| 78 // | 82 // |
| 79 // See http://sourceforge.net/p/stlport/bugs/239/. | 83 // See http://sourceforge.net/p/stlport/bugs/239/. |
| 80 typedef base::hash_map<int64, EntryKernel*> MetahandlesMap; | 84 typedef base::hash_map<int64, EntryKernel*> MetahandlesMap; |
| 81 typedef base::hash_map<std::string, EntryKernel*> IdsMap; | 85 typedef base::hash_map<std::string, EntryKernel*> IdsMap; |
| 82 typedef base::hash_map<std::string, EntryKernel*> TagsMap; | 86 typedef base::hash_map<std::string, EntryKernel*> TagsMap; |
| 87 typedef std::string AttachmentIdUniqueId; |
| 88 typedef base::hash_map<AttachmentIdUniqueId, MetahandleSet> |
| 89 IndexByAttachmenId; |
| 83 | 90 |
| 84 static const base::FilePath::CharType kSyncDatabaseFilename[]; | 91 static const base::FilePath::CharType kSyncDatabaseFilename[]; |
| 85 | 92 |
| 86 // The dirty/clean state of kernel fields backed by the share_info table. | 93 // The dirty/clean state of kernel fields backed by the share_info table. |
| 87 // This is public so it can be used in SaveChangesSnapshot for persistence. | 94 // This is public so it can be used in SaveChangesSnapshot for persistence. |
| 88 enum KernelShareInfoStatus { | 95 enum KernelShareInfoStatus { |
| 89 KERNEL_SHARE_INFO_INVALID, | 96 KERNEL_SHARE_INFO_INVALID, |
| 90 KERNEL_SHARE_INFO_VALID, | 97 KERNEL_SHARE_INFO_VALID, |
| 91 KERNEL_SHARE_INFO_DIRTY | 98 KERNEL_SHARE_INFO_DIRTY |
| 92 }; | 99 }; |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 376 // Returns: true on success, false if an error was encountered. | 383 // Returns: true on success, false if an error was encountered. |
| 377 virtual bool PurgeEntriesWithTypeIn(ModelTypeSet disabled_types, | 384 virtual bool PurgeEntriesWithTypeIn(ModelTypeSet disabled_types, |
| 378 ModelTypeSet types_to_journal, | 385 ModelTypeSet types_to_journal, |
| 379 ModelTypeSet types_to_unapply); | 386 ModelTypeSet types_to_unapply); |
| 380 | 387 |
| 381 // Resets the base_versions and server_versions of all synced entities | 388 // Resets the base_versions and server_versions of all synced entities |
| 382 // associated with |type| to 1. | 389 // associated with |type| to 1. |
| 383 // WARNING! This can be slow, as it iterates over all entries for a type. | 390 // WARNING! This can be slow, as it iterates over all entries for a type. |
| 384 bool ResetVersionsForType(BaseWriteTransaction* trans, ModelType type); | 391 bool ResetVersionsForType(BaseWriteTransaction* trans, ModelType type); |
| 385 | 392 |
| 393 // Returns true iff the attachment identified by |attachment_id| is linked to |
| 394 // an entry. |
| 395 // |
| 396 // An attachment linked to a deleted entry is still considered linked if the |
| 397 // entry hasn't yet been purged. |
| 398 bool IsAttachmentLinked(const AttachmentId& attachment_id) const; |
| 399 |
| 386 protected: // for friends, mainly used by Entry constructors | 400 protected: // for friends, mainly used by Entry constructors |
| 387 virtual EntryKernel* GetEntryByHandle(int64 handle); | 401 virtual EntryKernel* GetEntryByHandle(int64 handle); |
| 388 virtual EntryKernel* GetEntryByHandle(int64 metahandle, | 402 virtual EntryKernel* GetEntryByHandle(int64 metahandle, |
| 389 ScopedKernelLock* lock); | 403 ScopedKernelLock* lock); |
| 390 virtual EntryKernel* GetEntryById(const Id& id); | 404 virtual EntryKernel* GetEntryById(const Id& id); |
| 391 EntryKernel* GetEntryByServerTag(const std::string& tag); | 405 EntryKernel* GetEntryByServerTag(const std::string& tag); |
| 392 virtual EntryKernel* GetEntryByClientTag(const std::string& tag); | 406 virtual EntryKernel* GetEntryByClientTag(const std::string& tag); |
| 393 bool ReindexId(BaseWriteTransaction* trans, EntryKernel* const entry, | 407 bool ReindexId(BaseWriteTransaction* trans, EntryKernel* const entry, |
| 394 const Id& new_id); | 408 const Id& new_id); |
| 395 bool ReindexParentId(BaseWriteTransaction* trans, EntryKernel* const entry, | 409 bool ReindexParentId(BaseWriteTransaction* trans, EntryKernel* const entry, |
| 396 const Id& new_parent_id); | 410 const Id& new_parent_id); |
| 411 // Update the attachment index for |metahandle| removing it from the index |
| 412 // under |old_metadata| entries and add it under |new_metadata| entries. |
| 413 void UpdateAttachmentIndex(const int64 metahandle, |
| 414 const sync_pb::AttachmentMetadata& old_metadata, |
| 415 const sync_pb::AttachmentMetadata& new_metadata); |
| 397 void ClearDirtyMetahandles(); | 416 void ClearDirtyMetahandles(); |
| 398 | 417 |
| 399 DirOpenResult OpenImpl( | 418 DirOpenResult OpenImpl( |
| 400 const std::string& name, | 419 const std::string& name, |
| 401 DirectoryChangeDelegate* delegate, | 420 DirectoryChangeDelegate* delegate, |
| 402 const WeakHandle<TransactionObserver>& transaction_observer); | 421 const WeakHandle<TransactionObserver>& transaction_observer); |
| 403 | 422 |
| 404 private: | 423 private: |
| 405 struct Kernel { | 424 struct Kernel { |
| 406 // |delegate| must not be NULL. |transaction_observer| must be | 425 // |delegate| must not be NULL. |transaction_observer| must be |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 444 | 463 |
| 445 // Entries indexed by client tag. | 464 // Entries indexed by client tag. |
| 446 // This map does not include any entries with non-existent client tags. | 465 // This map does not include any entries with non-existent client tags. |
| 447 // IS_DEL items are included. | 466 // IS_DEL items are included. |
| 448 TagsMap client_tags_map; | 467 TagsMap client_tags_map; |
| 449 | 468 |
| 450 // Contains non-deleted items, indexed according to parent and position | 469 // Contains non-deleted items, indexed according to parent and position |
| 451 // within parent. Protected by the ScopedKernelLock. | 470 // within parent. Protected by the ScopedKernelLock. |
| 452 ParentChildIndex parent_child_index; | 471 ParentChildIndex parent_child_index; |
| 453 | 472 |
| 473 // This index keeps track of which metahandles refer to a given attachment. |
| 474 // Think of it as the inverse of EntryKernel's AttachmentMetadata Records. |
| 475 // |
| 476 // Because entries can be undeleted (e.g. PutIsDel(false)), entries should |
| 477 // not removed from the index until they are actually deleted from memory. |
| 478 // |
| 479 // All access should go through IsAttachmentLinked, |
| 480 // RemoveFromAttachmentIndex, AddToAttachmentIndex, and |
| 481 // UpdateAttachmentIndex methods to avoid iterator invalidation errors. |
| 482 IndexByAttachmenId index_by_attachment_id; |
| 483 |
| 454 // 3 in-memory indices on bits used extremely frequently by the syncer. | 484 // 3 in-memory indices on bits used extremely frequently by the syncer. |
| 455 // |unapplied_update_metahandles| is keyed by the server model type. | 485 // |unapplied_update_metahandles| is keyed by the server model type. |
| 456 MetahandleSet unapplied_update_metahandles[MODEL_TYPE_COUNT]; | 486 MetahandleSet unapplied_update_metahandles[MODEL_TYPE_COUNT]; |
| 457 MetahandleSet unsynced_metahandles; | 487 MetahandleSet unsynced_metahandles; |
| 458 // Contains metahandles that are most likely dirty (though not | 488 // Contains metahandles that are most likely dirty (though not |
| 459 // necessarily). Dirtyness is confirmed in TakeSnapshotForSaveChanges(). | 489 // necessarily). Dirtyness is confirmed in TakeSnapshotForSaveChanges(). |
| 460 MetahandleSet dirty_metahandles; | 490 MetahandleSet dirty_metahandles; |
| 461 | 491 |
| 462 // When a purge takes place, we remove items from all our indices and stash | 492 // When a purge takes place, we remove items from all our indices and stash |
| 463 // them in here so that SaveChanges can persist their permanent deletion. | 493 // them in here so that SaveChanges can persist their permanent deletion. |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 536 | 566 |
| 537 // Append the handles of the children of |parent_id| to |result|. | 567 // Append the handles of the children of |parent_id| to |result|. |
| 538 void AppendChildHandles( | 568 void AppendChildHandles( |
| 539 const ScopedKernelLock& lock, | 569 const ScopedKernelLock& lock, |
| 540 const Id& parent_id, Directory::Metahandles* result); | 570 const Id& parent_id, Directory::Metahandles* result); |
| 541 | 571 |
| 542 // Helper methods used by PurgeDisabledTypes. | 572 // Helper methods used by PurgeDisabledTypes. |
| 543 void UnapplyEntry(EntryKernel* entry); | 573 void UnapplyEntry(EntryKernel* entry); |
| 544 void DeleteEntry(bool save_to_journal, | 574 void DeleteEntry(bool save_to_journal, |
| 545 EntryKernel* entry, | 575 EntryKernel* entry, |
| 546 EntryKernelSet* entries_to_journal); | 576 EntryKernelSet* entries_to_journal, |
| 577 const ScopedKernelLock& lock); |
| 578 |
| 579 // Remove each of |metahandle|'s attachment ids from index_by_attachment_id. |
| 580 void RemoveFromAttachmentIndex( |
| 581 const int64 metahandle, |
| 582 const sync_pb::AttachmentMetadata& attachment_metadata, |
| 583 const ScopedKernelLock& lock); |
| 584 // Add each of |metahandle|'s attachment ids to the index_by_attachment_id. |
| 585 void AddToAttachmentIndex( |
| 586 const int64 metahandle, |
| 587 const sync_pb::AttachmentMetadata& attachment_metadata, |
| 588 const ScopedKernelLock& lock); |
| 547 | 589 |
| 548 Kernel* kernel_; | 590 Kernel* kernel_; |
| 549 | 591 |
| 550 scoped_ptr<DirectoryBackingStore> store_; | 592 scoped_ptr<DirectoryBackingStore> store_; |
| 551 | 593 |
| 552 UnrecoverableErrorHandler* const unrecoverable_error_handler_; | 594 UnrecoverableErrorHandler* const unrecoverable_error_handler_; |
| 553 const ReportUnrecoverableErrorFunction report_unrecoverable_error_function_; | 595 const ReportUnrecoverableErrorFunction report_unrecoverable_error_function_; |
| 554 bool unrecoverable_error_set_; | 596 bool unrecoverable_error_set_; |
| 555 | 597 |
| 556 // Not owned. | 598 // Not owned. |
| 557 NigoriHandler* const nigori_handler_; | 599 NigoriHandler* const nigori_handler_; |
| 558 Cryptographer* const cryptographer_; | 600 Cryptographer* const cryptographer_; |
| 559 | 601 |
| 560 InvariantCheckLevel invariant_check_level_; | 602 InvariantCheckLevel invariant_check_level_; |
| 561 | 603 |
| 562 // Maintain deleted entries not in |kernel_| until it's verified that they | 604 // Maintain deleted entries not in |kernel_| until it's verified that they |
| 563 // are deleted in native models as well. | 605 // are deleted in native models as well. |
| 564 scoped_ptr<DeleteJournal> delete_journal_; | 606 scoped_ptr<DeleteJournal> delete_journal_; |
| 565 | 607 |
| 566 DISALLOW_COPY_AND_ASSIGN(Directory); | 608 DISALLOW_COPY_AND_ASSIGN(Directory); |
| 567 }; | 609 }; |
| 568 | 610 |
| 569 } // namespace syncable | 611 } // namespace syncable |
| 570 } // namespace syncer | 612 } // namespace syncer |
| 571 | 613 |
| 572 #endif // SYNC_SYNCABLE_DIRECTORY_H_ | 614 #endif // SYNC_SYNCABLE_DIRECTORY_H_ |
| OLD | NEW |