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 |