Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: sync/syncable/directory.h

Issue 11636006: WIP: The Bookmark Position Megapatch (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Various updates, including switch suffix to unique_client_tag style Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « sync/sync.gyp ('k') | sync/syncable/directory.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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_
OLDNEW
« no previous file with comments | « sync/sync.gyp ('k') | sync/syncable/directory.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698