| OLD | NEW |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 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 <set> | 8 #include <set> |
| 9 #include <string> | 9 #include <string> |
| 10 #include <vector> | 10 #include <vector> |
| 11 | 11 |
| 12 #include "base/file_util.h" | 12 #include "base/file_util.h" |
| 13 #include "base/gtest_prod_util.h" | 13 #include "base/gtest_prod_util.h" |
| 14 #include "sync/base/sync_export.h" | 14 #include "sync/base/sync_export.h" |
| 15 #include "sync/internal_api/public/util/report_unrecoverable_error_function.h" | 15 #include "sync/internal_api/public/util/report_unrecoverable_error_function.h" |
| 16 #include "sync/internal_api/public/util/weak_handle.h" | 16 #include "sync/internal_api/public/util/weak_handle.h" |
| 17 #include "sync/syncable/dir_open_result.h" | 17 #include "sync/syncable/dir_open_result.h" |
| 18 #include "sync/syncable/entry_kernel.h" | 18 #include "sync/syncable/entry_kernel.h" |
| 19 #include "sync/syncable/metahandle_set.h" | 19 #include "sync/syncable/metahandle_set.h" |
| 20 #include "sync/syncable/parent_child_index.h" |
| 20 #include "sync/syncable/scoped_kernel_lock.h" | 21 #include "sync/syncable/scoped_kernel_lock.h" |
| 21 | 22 |
| 23 // TODO: Check this file for useless members. |
| 24 |
| 22 namespace syncer { | 25 namespace syncer { |
| 23 | 26 |
| 24 class Cryptographer; | 27 class Cryptographer; |
| 25 class UnrecoverableErrorHandler; | 28 class UnrecoverableErrorHandler; |
| 26 | 29 |
| 27 namespace syncable { | 30 namespace syncable { |
| 28 | 31 |
| 29 class BaseTransaction; | 32 class BaseTransaction; |
| 30 class DirectoryChangeDelegate; | 33 class DirectoryChangeDelegate; |
| 31 class DirectoryBackingStore; | 34 class DirectoryBackingStore; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 77 | 80 |
| 78 // Traits type for unique client tag index. | 81 // Traits type for unique client tag index. |
| 79 struct ClientTagIndexer { | 82 struct ClientTagIndexer { |
| 80 // This index is of the client-tag values. | 83 // This index is of the client-tag values. |
| 81 typedef LessField<StringField, UNIQUE_CLIENT_TAG> Comparator; | 84 typedef LessField<StringField, UNIQUE_CLIENT_TAG> Comparator; |
| 82 | 85 |
| 83 // Items are only in this index if they have a non-empty client tag value. | 86 // Items are only in this index if they have a non-empty client tag value. |
| 84 static bool ShouldInclude(const EntryKernel* a); | 87 static bool ShouldInclude(const EntryKernel* a); |
| 85 }; | 88 }; |
| 86 | 89 |
| 87 // This index contains EntryKernels ordered by parent ID and metahandle. | |
| 88 // It allows efficient lookup of the children of a given parent. | |
| 89 struct ParentIdAndHandleIndexer { | |
| 90 // This index is of the parent ID and metahandle. We use a custom | |
| 91 // comparator. | |
| 92 class Comparator { | |
| 93 public: | |
| 94 bool operator() (const syncable::EntryKernel* a, | |
| 95 const syncable::EntryKernel* b) const; | |
| 96 }; | |
| 97 | |
| 98 // This index does not include deleted items. | |
| 99 static bool ShouldInclude(const EntryKernel* a); | |
| 100 }; | |
| 101 | |
| 102 // Given an Indexer providing the semantics of an index, defines the | 90 // Given an Indexer providing the semantics of an index, defines the |
| 103 // set type used to actually contain the index. | 91 // set type used to actually contain the index. |
| 104 template <typename Indexer> | 92 template <typename Indexer> |
| 105 struct Index { | 93 struct Index { |
| 106 typedef std::set<EntryKernel*, typename Indexer::Comparator> Set; | 94 typedef std::set<EntryKernel*, typename Indexer::Comparator> Set; |
| 107 }; | 95 }; |
| 108 | 96 |
| 97 |
| 98 |
| 109 // Reason for unlinking. | 99 // Reason for unlinking. |
| 110 enum UnlinkReason { | 100 enum UnlinkReason { |
| 111 NODE_MANIPULATION, // To be used by any operation manipulating the linked | 101 NODE_MANIPULATION, // To be used by any operation manipulating the linked |
| 112 // list. | 102 // list. |
| 113 DATA_TYPE_PURGE // To be used when purging a dataype. | 103 DATA_TYPE_PURGE // To be used when purging a dataype. |
| 114 }; | 104 }; |
| 115 | 105 |
| 116 class EntryKernelLessByMetaHandle { | 106 class EntryKernelLessByMetaHandle { |
| 117 public: | 107 public: |
| 118 inline bool operator()(const EntryKernel& a, | 108 inline bool operator()(const EntryKernel& a, |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 232 DirOpenResult Open(const std::string& name, | 222 DirOpenResult Open(const std::string& name, |
| 233 DirectoryChangeDelegate* delegate, | 223 DirectoryChangeDelegate* delegate, |
| 234 const WeakHandle<TransactionObserver>& | 224 const WeakHandle<TransactionObserver>& |
| 235 transaction_observer); | 225 transaction_observer); |
| 236 | 226 |
| 237 // Stops sending events to the delegate and the transaction | 227 // Stops sending events to the delegate and the transaction |
| 238 // observer. | 228 // observer. |
| 239 void Close(); | 229 void Close(); |
| 240 | 230 |
| 241 int64 NextMetahandle(); | 231 int64 NextMetahandle(); |
| 242 // Always returns a negative id. Positive client ids are generated | 232 // Returns a negative integer unique to this client. |
| 243 // by the server only. | 233 syncable::Id NextId(); |
| 244 Id NextId(); | |
| 245 | 234 |
| 246 bool good() const { return NULL != kernel_; } | 235 bool good() const { return NULL != kernel_; } |
| 247 | 236 |
| 248 // The download progress is an opaque token provided by the sync server | 237 // The download progress is an opaque token provided by the sync server |
| 249 // to indicate the continuation state of the next GetUpdates operation. | 238 // to indicate the continuation state of the next GetUpdates operation. |
| 250 void GetDownloadProgress( | 239 void GetDownloadProgress( |
| 251 ModelType type, | 240 ModelType type, |
| 252 sync_pb::DataTypeProgressMarker* value_out) const; | 241 sync_pb::DataTypeProgressMarker* value_out) const; |
| 253 void GetDownloadProgressAsString( | 242 void GetDownloadProgressAsString( |
| 254 ModelType type, | 243 ModelType type, |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 320 virtual EntryKernel* GetEntryById(const Id& id); | 309 virtual EntryKernel* GetEntryById(const Id& id); |
| 321 EntryKernel* GetEntryByServerTag(const std::string& tag); | 310 EntryKernel* GetEntryByServerTag(const std::string& tag); |
| 322 virtual EntryKernel* GetEntryByClientTag(const std::string& tag); | 311 virtual EntryKernel* GetEntryByClientTag(const std::string& tag); |
| 323 EntryKernel* GetRootEntry(); | 312 EntryKernel* GetRootEntry(); |
| 324 bool ReindexId(WriteTransaction* trans, EntryKernel* const entry, | 313 bool ReindexId(WriteTransaction* trans, EntryKernel* const entry, |
| 325 const Id& new_id); | 314 const Id& new_id); |
| 326 bool ReindexParentId(WriteTransaction* trans, EntryKernel* const entry, | 315 bool ReindexParentId(WriteTransaction* trans, EntryKernel* const entry, |
| 327 const Id& new_parent_id); | 316 const Id& new_parent_id); |
| 328 void ClearDirtyMetahandles(); | 317 void ClearDirtyMetahandles(); |
| 329 | 318 |
| 330 // These don't do semantic checking. | |
| 331 // The semantic checking is implemented higher up. | |
| 332 bool UnlinkEntryFromOrder(EntryKernel* entry, | |
| 333 WriteTransaction* trans, | |
| 334 ScopedKernelLock* lock, | |
| 335 UnlinkReason unlink_reason); | |
| 336 | |
| 337 DirOpenResult OpenImpl( | 319 DirOpenResult OpenImpl( |
| 338 const std::string& name, | 320 const std::string& name, |
| 339 DirectoryChangeDelegate* delegate, | 321 DirectoryChangeDelegate* delegate, |
| 340 const WeakHandle<TransactionObserver>& transaction_observer); | 322 const WeakHandle<TransactionObserver>& transaction_observer); |
| 341 | 323 |
| 342 private: | 324 private: |
| 343 // These private versions expect the kernel lock to already be held | 325 // These private versions expect the kernel lock to already be held |
| 344 // before calling. | 326 // before calling. |
| 345 EntryKernel* GetEntryById(const Id& id, ScopedKernelLock* const lock); | 327 EntryKernel* GetEntryById(const Id& id, ScopedKernelLock* const lock); |
| 346 | 328 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 361 bool GetChildHandlesByHandle(BaseTransaction*, int64 handle, | 343 bool GetChildHandlesByHandle(BaseTransaction*, int64 handle, |
| 362 ChildHandles* result); | 344 ChildHandles* result); |
| 363 | 345 |
| 364 // Returns true iff |id| has children. | 346 // Returns true iff |id| has children. |
| 365 bool HasChildren(BaseTransaction* trans, const Id& id); | 347 bool HasChildren(BaseTransaction* trans, const Id& id); |
| 366 | 348 |
| 367 // Find the first child in the positional ordering under a parent, | 349 // Find the first child in the positional ordering under a parent, |
| 368 // and fill in |*first_child_id| with its id. Fills in a root Id if | 350 // and fill in |*first_child_id| with its id. Fills in a root Id if |
| 369 // parent has no children. Returns true if the first child was | 351 // parent has no children. Returns true if the first child was |
| 370 // successfully found, or false if an error was encountered. | 352 // successfully found, or false if an error was encountered. |
| 371 bool GetFirstChildId(BaseTransaction* trans, const Id& parent_id, | 353 Id GetFirstChildId(BaseTransaction* trans, const EntryKernel* parent); |
| 372 Id* first_child_id) WARN_UNUSED_RESULT; | |
| 373 | 354 |
| 374 // Find the last child in the positional ordering under a parent, | 355 // These functions allow one to fetch the next or previous item under |
| 375 // and fill in |*first_child_id| with its id. Fills in a root Id if | 356 // the same folder. Returns the "root" ID if there is no predecessor |
| 376 // parent has no children. Returns true if the first child was | 357 // or successor. |
| 377 // successfully found, or false if an error was encountered. | 358 // |
| 378 bool GetLastChildIdForTest(BaseTransaction* trans, const Id& parent_id, | 359 // TODO(rlarocque): These functions are used mainly for tree traversal. We |
| 379 Id* last_child_id) WARN_UNUSED_RESULT; | 360 // should replace these with an iterator API. |
| 361 syncable::Id GetPredecessorId(EntryKernel*); |
| 362 syncable::Id GetSuccessorId(EntryKernel*); |
| 380 | 363 |
| 381 // Compute a local predecessor position for |update_item|. The position | 364 // Places |e| as a successor to |predecessor|. If |predecessor| is NULL, |
| 382 // is determined by the SERVER_POSITION_IN_PARENT value of |update_item|, | 365 // |e| will be placed as the left-most item in its folder. |
| 383 // as well as the SERVER_POSITION_IN_PARENT values of any up-to-date | 366 // |
| 384 // children of |parent_id|. | 367 // Both |e| and |predecessor| must be valid entries under the same parent. |
| 385 Id ComputePrevIdFromServerPosition( | 368 // |
| 386 const EntryKernel* update_item, | 369 // TODO(rlarocque): This function includes limited support for placing items |
| 387 const syncable::Id& parent_id); | 370 // with valid positions (ie. Bookmarks) as siblings of items that have no set |
| 371 // ordering (ie. Autofill items). This support is required only for tests, |
| 372 // and should be removed. |
| 373 void PutPredecessor(EntryKernel* e, EntryKernel* predecessor); |
| 388 | 374 |
| 389 // SaveChanges works by taking a consistent snapshot of the current Directory | 375 // SaveChanges works by taking a consistent snapshot of the current Directory |
| 390 // state and indices (by deep copy) under a ReadTransaction, passing this | 376 // state and indices (by deep copy) under a ReadTransaction, passing this |
| 391 // snapshot to the backing store under no transaction, and finally cleaning | 377 // snapshot to the backing store under no transaction, and finally cleaning |
| 392 // up by either purging entries no longer needed (this part done under a | 378 // up by either purging entries no longer needed (this part done under a |
| 393 // WriteTransaction) or rolling back the dirty bits. It also uses | 379 // WriteTransaction) or rolling back the dirty bits. It also uses |
| 394 // internal locking to enforce SaveChanges operations are mutually exclusive. | 380 // internal locking to enforce SaveChanges operations are mutually exclusive. |
| 395 // | 381 // |
| 396 // WARNING: THIS METHOD PERFORMS SYNCHRONOUS I/O VIA SQLITE. | 382 // WARNING: THIS METHOD PERFORMS SYNCHRONOUS I/O VIA SQLITE. |
| 397 bool SaveChanges(); | 383 bool SaveChanges(); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 487 const EntryKernel* const entry) const; | 473 const EntryKernel* const entry) const; |
| 488 | 474 |
| 489 // Internal setters that do not acquire a lock internally. These are unsafe | 475 // Internal setters that do not acquire a lock internally. These are unsafe |
| 490 // on their own; caller must guarantee exclusive access manually by holding | 476 // on their own; caller must guarantee exclusive access manually by holding |
| 491 // a ScopedKernelLock. | 477 // a ScopedKernelLock. |
| 492 void SetNotificationStateUnsafe(const std::string& notification_state); | 478 void SetNotificationStateUnsafe(const std::string& notification_state); |
| 493 | 479 |
| 494 Directory& operator = (const Directory&); | 480 Directory& operator = (const Directory&); |
| 495 | 481 |
| 496 public: | 482 public: |
| 483 // These contain all items, including IS_DEL items. |
| 497 typedef Index<MetahandleIndexer>::Set MetahandlesIndex; | 484 typedef Index<MetahandleIndexer>::Set MetahandlesIndex; |
| 498 typedef Index<IdIndexer>::Set IdsIndex; | 485 typedef Index<IdIndexer>::Set IdsIndex; |
| 499 // All entries in memory must be in both the MetahandlesIndex and | |
| 500 // the IdsIndex, but only non-deleted entries will be the | |
| 501 // ParentIdChildIndex. | |
| 502 typedef Index<ParentIdAndHandleIndexer>::Set ParentIdChildIndex; | |
| 503 | 486 |
| 504 // Contains both deleted and existing entries with tags. | 487 // Contains both deleted and existing entries with tags. |
| 505 // We can't store only existing tags because the client would create | 488 // We can't store only existing tags because the client would create |
| 506 // items that had a duplicated ID in the end, resulting in a DB key | 489 // items that had a duplicated ID in the end, resulting in a DB key |
| 507 // violation. ID reassociation would fail after an attempted commit. | 490 // violation. ID reassociation would fail after an attempted commit. |
| 508 typedef Index<ClientTagIndexer>::Set ClientTagIndex; | 491 typedef Index<ClientTagIndexer>::Set ClientTagIndex; |
| 509 | 492 |
| 510 protected: | 493 protected: |
| 511 // Used by tests. |delegate| must not be NULL. | 494 // Used by tests. |delegate| must not be NULL. |
| 512 // |transaction_observer| must be initialized. | 495 // |transaction_observer| must be initialized. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 539 // entries themselves. So once a pointer to an entry is pulled | 522 // entries themselves. So once a pointer to an entry is pulled |
| 540 // from the index, the mutex can be unlocked and entry read or written. | 523 // from the index, the mutex can be unlocked and entry read or written. |
| 541 // | 524 // |
| 542 // Never hold the mutex and do anything with the database or any | 525 // Never hold the mutex and do anything with the database or any |
| 543 // other buffered IO. Violating this rule will result in deadlock. | 526 // other buffered IO. Violating this rule will result in deadlock. |
| 544 base::Lock mutex; | 527 base::Lock mutex; |
| 545 // Entries indexed by metahandle | 528 // Entries indexed by metahandle |
| 546 MetahandlesIndex* metahandles_index; | 529 MetahandlesIndex* metahandles_index; |
| 547 // Entries indexed by id | 530 // Entries indexed by id |
| 548 IdsIndex* ids_index; | 531 IdsIndex* ids_index; |
| 549 ParentIdChildIndex* parent_id_child_index; | 532 |
| 533 // Contains non-deleted items, indexed according to parent and position |
| 534 // within parent. Protected by the ScopedKernelLock. |
| 535 ParentChildIndex* parent_child_index; |
| 536 |
| 550 ClientTagIndex* client_tag_index; | 537 ClientTagIndex* client_tag_index; |
| 551 // So we don't have to create an EntryKernel every time we want to | 538 // So we don't have to create an EntryKernel every time we want to |
| 552 // look something up in an index. Needle in haystack metaphor. | 539 // look something up in an index. Needle in haystack metaphor. |
| 553 EntryKernel needle; | 540 EntryKernel needle; |
| 554 | 541 |
| 555 // 3 in-memory indices on bits used extremely frequently by the syncer. | 542 // 3 in-memory indices on bits used extremely frequently by the syncer. |
| 556 // |unapplied_update_metahandles| is keyed by the server model type. | 543 // |unapplied_update_metahandles| is keyed by the server model type. |
| 557 MetahandleSet unapplied_update_metahandles[MODEL_TYPE_COUNT]; | 544 MetahandleSet unapplied_update_metahandles[MODEL_TYPE_COUNT]; |
| 558 MetahandleSet* const unsynced_metahandles; | 545 MetahandleSet* const unsynced_metahandles; |
| 559 // Contains metahandles that are most likely dirty (though not | 546 // Contains metahandles that are most likely dirty (though not |
| (...skipping 24 matching lines...) Expand all Loading... |
| 584 // The next metahandle is protected by kernel mutex. | 571 // The next metahandle is protected by kernel mutex. |
| 585 int64 next_metahandle; | 572 int64 next_metahandle; |
| 586 | 573 |
| 587 // The delegate for directory change events. Must not be NULL. | 574 // The delegate for directory change events. Must not be NULL. |
| 588 DirectoryChangeDelegate* const delegate; | 575 DirectoryChangeDelegate* const delegate; |
| 589 | 576 |
| 590 // The transaction observer. | 577 // The transaction observer. |
| 591 const WeakHandle<TransactionObserver> transaction_observer; | 578 const WeakHandle<TransactionObserver> transaction_observer; |
| 592 }; | 579 }; |
| 593 | 580 |
| 594 // Helper method used to do searches on |parent_id_child_index|. | |
| 595 ParentIdChildIndex::iterator LocateInParentChildIndex( | |
| 596 const ScopedKernelLock& lock, | |
| 597 const Id& parent_id, | |
| 598 int64 position_in_parent, | |
| 599 const Id& item_id_for_tiebreaking); | |
| 600 | |
| 601 // Return an iterator to the beginning of the range of the children of | |
| 602 // |parent_id| in the kernel's parent_id_child_index. | |
| 603 ParentIdChildIndex::iterator GetParentChildIndexLowerBound( | |
| 604 const ScopedKernelLock& lock, | |
| 605 const Id& parent_id); | |
| 606 | |
| 607 // Return an iterator to just past the end of the range of the | |
| 608 // children of |parent_id| in the kernel's parent_id_child_index. | |
| 609 ParentIdChildIndex::iterator GetParentChildIndexUpperBound( | |
| 610 const ScopedKernelLock& lock, | |
| 611 const Id& parent_id); | |
| 612 | |
| 613 // Append the handles of the children of |parent_id| to |result|. | 581 // Append the handles of the children of |parent_id| to |result|. |
| 614 void AppendChildHandles( | 582 void AppendChildHandles( |
| 615 const ScopedKernelLock& lock, | 583 const ScopedKernelLock& lock, |
| 616 const Id& parent_id, Directory::ChildHandles* result); | 584 const Id& parent_id, Directory::ChildHandles* result); |
| 617 | 585 |
| 618 // Return a pointer to what is probably (but not certainly) the | |
| 619 // first child of |parent_id|, or NULL if |parent_id| definitely has | |
| 620 // no children. | |
| 621 EntryKernel* GetPossibleFirstChild( | |
| 622 const ScopedKernelLock& lock, const Id& parent_id); | |
| 623 | |
| 624 Kernel* kernel_; | 586 Kernel* kernel_; |
| 625 | 587 |
| 626 scoped_ptr<DirectoryBackingStore> store_; | 588 scoped_ptr<DirectoryBackingStore> store_; |
| 627 | 589 |
| 628 UnrecoverableErrorHandler* const unrecoverable_error_handler_; | 590 UnrecoverableErrorHandler* const unrecoverable_error_handler_; |
| 629 const ReportUnrecoverableErrorFunction report_unrecoverable_error_function_; | 591 const ReportUnrecoverableErrorFunction report_unrecoverable_error_function_; |
| 630 bool unrecoverable_error_set_; | 592 bool unrecoverable_error_set_; |
| 631 | 593 |
| 632 // Not owned. | 594 // Not owned. |
| 633 NigoriHandler* const nigori_handler_; | 595 NigoriHandler* const nigori_handler_; |
| 634 Cryptographer* const cryptographer_; | 596 Cryptographer* const cryptographer_; |
| 635 | 597 |
| 636 InvariantCheckLevel invariant_check_level_; | 598 InvariantCheckLevel invariant_check_level_; |
| 637 }; | 599 }; |
| 638 | 600 |
| 639 } // namespace syncable | 601 } // namespace syncable |
| 640 } // namespace syncer | 602 } // namespace syncer |
| 641 | 603 |
| 642 #endif // SYNC_SYNCABLE_DIRECTORY_H_ | 604 #endif // SYNC_SYNCABLE_DIRECTORY_H_ |
| OLD | NEW |