• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3 // found in the LICENSE file.
4 
5 #ifndef CHROME_BROWSER_SYNC_SYNCABLE_SYNCABLE_H_
6 #define CHROME_BROWSER_SYNC_SYNCABLE_SYNCABLE_H_
7 #pragma once
8 
9 #include <algorithm>
10 #include <bitset>
11 #include <iosfwd>
12 #include <limits>
13 #include <set>
14 #include <string>
15 #include <vector>
16 
17 #include "base/atomicops.h"
18 #include "base/basictypes.h"
19 #include "base/file_path.h"
20 #include "base/gtest_prod_util.h"
21 #include "base/synchronization/lock.h"
22 #include "base/time.h"
23 #include "chrome/browser/sync/protocol/sync.pb.h"
24 #include "chrome/browser/sync/syncable/autofill_migration.h"
25 #include "chrome/browser/sync/syncable/blob.h"
26 #include "chrome/browser/sync/syncable/dir_open_result.h"
27 #include "chrome/browser/sync/syncable/directory_event.h"
28 #include "chrome/browser/sync/syncable/syncable_id.h"
29 #include "chrome/browser/sync/syncable/model_type.h"
30 #include "chrome/browser/sync/util/dbgq.h"
31 #include "chrome/common/deprecated/event_sys.h"
32 
33 class DictionaryValue;
34 struct PurgeInfo;
35 
36 namespace sync_api {
37 class ReadTransaction;
38 class WriteNode;
39 class ReadNode;
40 }
41 
42 namespace syncable {
43 class DirectoryChangeListener;
44 class Entry;
45 
46 std::ostream& operator<<(std::ostream& s, const Entry& e);
47 
48 class DirectoryBackingStore;
49 
50 static const int64 kInvalidMetaHandle = 0;
51 
52 // Update syncable_enum_conversions{.h,.cc,_unittest.cc} if you change
53 // any fields in this file.
54 
55 enum {
56   BEGIN_FIELDS = 0,
57   INT64_FIELDS_BEGIN = BEGIN_FIELDS
58 };
59 
60 enum MetahandleField {
61   // Primary key into the table.  Keep this as a handle to the meta entry
62   // across transactions.
63   META_HANDLE = INT64_FIELDS_BEGIN
64 };
65 
66 enum BaseVersion {
67   // After initial upload, the version is controlled by the server, and is
68   // increased whenever the data or metadata changes on the server.
69   BASE_VERSION = META_HANDLE + 1,
70 };
71 
72 enum Int64Field {
73   SERVER_VERSION = BASE_VERSION + 1,
74   MTIME,
75   SERVER_MTIME,
76   CTIME,
77   SERVER_CTIME,
78 
79   // A numeric position value that indicates the relative ordering of
80   // this object among its siblings.
81   SERVER_POSITION_IN_PARENT,
82 
83   LOCAL_EXTERNAL_ID,  // ID of an item in the external local storage that this
84                       // entry is associated with. (such as bookmarks.js)
85 
86   INT64_FIELDS_END
87 };
88 
89 enum {
90   INT64_FIELDS_COUNT = INT64_FIELDS_END,
91   ID_FIELDS_BEGIN = INT64_FIELDS_END,
92 };
93 
94 enum IdField {
95   // Code in InitializeTables relies on ID being the first IdField value.
96   ID = ID_FIELDS_BEGIN,
97   PARENT_ID,
98   SERVER_PARENT_ID,
99 
100   PREV_ID,
101   NEXT_ID,
102   ID_FIELDS_END
103 };
104 
105 enum {
106   ID_FIELDS_COUNT = ID_FIELDS_END - ID_FIELDS_BEGIN,
107   BIT_FIELDS_BEGIN = ID_FIELDS_END
108 };
109 
110 enum IndexedBitField {
111   IS_UNSYNCED = BIT_FIELDS_BEGIN,
112   IS_UNAPPLIED_UPDATE,
113   INDEXED_BIT_FIELDS_END,
114 };
115 
116 enum IsDelField {
117   IS_DEL = INDEXED_BIT_FIELDS_END,
118 };
119 
120 enum BitField {
121   IS_DIR = IS_DEL + 1,
122   SERVER_IS_DIR,
123   SERVER_IS_DEL,
124   BIT_FIELDS_END
125 };
126 
127 enum {
128   BIT_FIELDS_COUNT = BIT_FIELDS_END - BIT_FIELDS_BEGIN,
129   STRING_FIELDS_BEGIN = BIT_FIELDS_END
130 };
131 
132 enum StringField {
133   // Name, will be truncated by server. Can be duplicated in a folder.
134   NON_UNIQUE_NAME = STRING_FIELDS_BEGIN,
135   // The server version of |NON_UNIQUE_NAME|.
136   SERVER_NON_UNIQUE_NAME,
137 
138   // A tag string which identifies this node as a particular top-level
139   // permanent object.  The tag can be thought of as a unique key that
140   // identifies a singleton instance.
141   UNIQUE_SERVER_TAG,  // Tagged by the server
142   UNIQUE_CLIENT_TAG,  // Tagged by the client
143   STRING_FIELDS_END,
144 };
145 
146 enum {
147   STRING_FIELDS_COUNT = STRING_FIELDS_END - STRING_FIELDS_BEGIN,
148   PROTO_FIELDS_BEGIN = STRING_FIELDS_END
149 };
150 
151 // From looking at the sqlite3 docs, it's not directly stated, but it
152 // seems the overhead for storing a NULL blob is very small.
153 enum ProtoField {
154   SPECIFICS = PROTO_FIELDS_BEGIN,
155   SERVER_SPECIFICS,
156   PROTO_FIELDS_END,
157 };
158 
159 enum {
160   PROTO_FIELDS_COUNT = PROTO_FIELDS_END - PROTO_FIELDS_BEGIN
161 };
162 
163 enum {
164   FIELD_COUNT = PROTO_FIELDS_END,
165   // Past this point we have temporaries, stored in memory only.
166   BEGIN_TEMPS = PROTO_FIELDS_END,
167   BIT_TEMPS_BEGIN = BEGIN_TEMPS,
168 };
169 
170 enum BitTemp {
171   SYNCING = BIT_TEMPS_BEGIN,
172   BIT_TEMPS_END,
173 };
174 
175 enum {
176   BIT_TEMPS_COUNT = BIT_TEMPS_END - BIT_TEMPS_BEGIN
177 };
178 
179 class BaseTransaction;
180 class WriteTransaction;
181 class ReadTransaction;
182 class Directory;
183 class ScopedDirLookup;
184 
185 // Instead of:
186 //   Entry e = transaction.GetById(id);
187 // use:
188 //   Entry e(transaction, GET_BY_ID, id);
189 //
190 // Why?  The former would require a copy constructor, and it would be difficult
191 // to enforce that an entry never outlived its transaction if there were a copy
192 // constructor.
193 enum GetById {
194   GET_BY_ID
195 };
196 
197 enum GetByClientTag {
198   GET_BY_CLIENT_TAG
199 };
200 
201 enum GetByServerTag {
202   GET_BY_SERVER_TAG
203 };
204 
205 enum GetByHandle {
206   GET_BY_HANDLE
207 };
208 
209 enum Create {
210   CREATE
211 };
212 
213 enum CreateNewUpdateItem {
214   CREATE_NEW_UPDATE_ITEM
215 };
216 
217 typedef std::set<int64> MetahandleSet;
218 
219 // Why the singular enums?  So the code compile-time dispatches instead of
220 // runtime dispatches as it would with a single enum and an if() statement.
221 
222 // The EntryKernel class contains the actual data for an entry.
223 struct EntryKernel {
224  private:
225   std::string string_fields[STRING_FIELDS_COUNT];
226   sync_pb::EntitySpecifics specifics_fields[PROTO_FIELDS_COUNT];
227   int64 int64_fields[INT64_FIELDS_COUNT];
228   Id id_fields[ID_FIELDS_COUNT];
229   std::bitset<BIT_FIELDS_COUNT> bit_fields;
230   std::bitset<BIT_TEMPS_COUNT> bit_temps;
231 
232  public:
233   EntryKernel();
234   ~EntryKernel();
235 
236   // Set the dirty bit, and optionally add this entry's metahandle to
237   // a provided index on dirty bits in |dirty_index|. Parameter may be null,
238   // and will result only in setting the dirty bit of this entry.
mark_dirtyEntryKernel239   inline void mark_dirty(syncable::MetahandleSet* dirty_index) {
240     if (!dirty_ && dirty_index) {
241       DCHECK_NE(0, ref(META_HANDLE));
242       dirty_index->insert(ref(META_HANDLE));
243     }
244     dirty_ = true;
245   }
246 
247   // Clear the dirty bit, and optionally remove this entry's metahandle from
248   // a provided index on dirty bits in |dirty_index|. Parameter may be null,
249   // and will result only in clearing dirty bit of this entry.
clear_dirtyEntryKernel250   inline void clear_dirty(syncable::MetahandleSet* dirty_index) {
251     if (dirty_ && dirty_index) {
252       DCHECK_NE(0, ref(META_HANDLE));
253       dirty_index->erase(ref(META_HANDLE));
254     }
255     dirty_ = false;
256   }
257 
is_dirtyEntryKernel258   inline bool is_dirty() const {
259     return dirty_;
260   }
261 
262   // Setters.
putEntryKernel263   inline void put(MetahandleField field, int64 value) {
264     int64_fields[field - INT64_FIELDS_BEGIN] = value;
265   }
putEntryKernel266   inline void put(Int64Field field, int64 value) {
267     int64_fields[field - INT64_FIELDS_BEGIN] = value;
268   }
putEntryKernel269   inline void put(IdField field, const Id& value) {
270     id_fields[field - ID_FIELDS_BEGIN] = value;
271   }
putEntryKernel272   inline void put(BaseVersion field, int64 value) {
273     int64_fields[field - INT64_FIELDS_BEGIN] = value;
274   }
putEntryKernel275   inline void put(IndexedBitField field, bool value) {
276     bit_fields[field - BIT_FIELDS_BEGIN] = value;
277   }
putEntryKernel278   inline void put(IsDelField field, bool value) {
279     bit_fields[field - BIT_FIELDS_BEGIN] = value;
280   }
putEntryKernel281   inline void put(BitField field, bool value) {
282     bit_fields[field - BIT_FIELDS_BEGIN] = value;
283   }
putEntryKernel284   inline void put(StringField field, const std::string& value) {
285     string_fields[field - STRING_FIELDS_BEGIN] = value;
286   }
putEntryKernel287   inline void put(ProtoField field, const sync_pb::EntitySpecifics& value) {
288     specifics_fields[field - PROTO_FIELDS_BEGIN].CopyFrom(value);
289   }
putEntryKernel290   inline void put(BitTemp field, bool value) {
291     bit_temps[field - BIT_TEMPS_BEGIN] = value;
292   }
293 
294   // Const ref getters.
refEntryKernel295   inline int64 ref(MetahandleField field) const {
296     return int64_fields[field - INT64_FIELDS_BEGIN];
297   }
refEntryKernel298   inline int64 ref(Int64Field field) const {
299     return int64_fields[field - INT64_FIELDS_BEGIN];
300   }
refEntryKernel301   inline const Id& ref(IdField field) const {
302     return id_fields[field - ID_FIELDS_BEGIN];
303   }
refEntryKernel304   inline int64 ref(BaseVersion field) const {
305     return int64_fields[field - INT64_FIELDS_BEGIN];
306   }
refEntryKernel307   inline bool ref(IndexedBitField field) const {
308     return bit_fields[field - BIT_FIELDS_BEGIN];
309   }
refEntryKernel310   inline bool ref(IsDelField field) const {
311     return bit_fields[field - BIT_FIELDS_BEGIN];
312   }
refEntryKernel313   inline bool ref(BitField field) const {
314     return bit_fields[field - BIT_FIELDS_BEGIN];
315   }
refEntryKernel316   inline const std::string& ref(StringField field) const {
317     return string_fields[field - STRING_FIELDS_BEGIN];
318   }
refEntryKernel319   inline const sync_pb::EntitySpecifics& ref(ProtoField field) const {
320     return specifics_fields[field - PROTO_FIELDS_BEGIN];
321   }
refEntryKernel322   inline bool ref(BitTemp field) const {
323     return bit_temps[field - BIT_TEMPS_BEGIN];
324   }
325 
326   // Non-const, mutable ref getters for object types only.
mutable_refEntryKernel327   inline std::string& mutable_ref(StringField field) {
328     return string_fields[field - STRING_FIELDS_BEGIN];
329   }
mutable_refEntryKernel330   inline sync_pb::EntitySpecifics& mutable_ref(ProtoField field) {
331     return specifics_fields[field - PROTO_FIELDS_BEGIN];
332   }
mutable_refEntryKernel333   inline Id& mutable_ref(IdField field) {
334     return id_fields[field - ID_FIELDS_BEGIN];
335   }
336 
337   // Dumps all kernel info into a DictionaryValue and returns it.
338   // Transfers ownership of the DictionaryValue to the caller.
339   DictionaryValue* ToValue() const;
340 
341  private:
342   // Tracks whether this entry needs to be saved to the database.
343   bool dirty_;
344 };
345 
346 // A read-only meta entry.
347 class Entry {
348   friend class Directory;
349   friend std::ostream& operator << (std::ostream& s, const Entry& e);
350 
351  public:
352   // After constructing, you must check good() to test whether the Get
353   // succeeded.
354   Entry(BaseTransaction* trans, GetByHandle, int64 handle);
355   Entry(BaseTransaction* trans, GetById, const Id& id);
356   Entry(BaseTransaction* trans, GetByServerTag, const std::string& tag);
357   Entry(BaseTransaction* trans, GetByClientTag, const std::string& tag);
358 
good()359   bool good() const { return 0 != kernel_; }
360 
trans()361   BaseTransaction* trans() const { return basetrans_; }
362 
363   // Field accessors.
Get(MetahandleField field)364   inline int64 Get(MetahandleField field) const {
365     DCHECK(kernel_);
366     return kernel_->ref(field);
367   }
Get(IdField field)368   inline Id Get(IdField field) const {
369     DCHECK(kernel_);
370     return kernel_->ref(field);
371   }
Get(Int64Field field)372   inline int64 Get(Int64Field field) const {
373     DCHECK(kernel_);
374     return kernel_->ref(field);
375   }
Get(BaseVersion field)376   inline int64 Get(BaseVersion field) const {
377     DCHECK(kernel_);
378     return kernel_->ref(field);
379   }
Get(IndexedBitField field)380   inline bool Get(IndexedBitField field) const {
381     DCHECK(kernel_);
382     return kernel_->ref(field);
383   }
Get(IsDelField field)384   inline bool Get(IsDelField field) const {
385     DCHECK(kernel_);
386     return kernel_->ref(field);
387   }
Get(BitField field)388   inline bool Get(BitField field) const {
389     DCHECK(kernel_);
390     return kernel_->ref(field);
391   }
392   const std::string& Get(StringField field) const;
Get(ProtoField field)393   inline const sync_pb::EntitySpecifics& Get(ProtoField field) const {
394     DCHECK(kernel_);
395     return kernel_->ref(field);
396   }
Get(BitTemp field)397   inline bool Get(BitTemp field) const {
398     DCHECK(kernel_);
399     return kernel_->ref(field);
400   }
401 
402   ModelType GetServerModelType() const;
403   ModelType GetModelType() const;
404 
405   // If this returns false, we shouldn't bother maintaining
406   // a position value (sibling ordering) for this item.
ShouldMaintainPosition()407   bool ShouldMaintainPosition() const {
408     return GetModelType() == BOOKMARKS;
409   }
410 
ExistsOnClientBecauseNameIsNonEmpty()411   inline bool ExistsOnClientBecauseNameIsNonEmpty() const {
412     DCHECK(kernel_);
413     return !kernel_->ref(NON_UNIQUE_NAME).empty();
414   }
415 
IsRoot()416   inline bool IsRoot() const {
417     DCHECK(kernel_);
418     return kernel_->ref(ID).IsRoot();
419   }
420 
421   Directory* dir() const;
422 
GetKernelCopy()423   const EntryKernel GetKernelCopy() const {
424     return *kernel_;
425   }
426 
427   // Compute a local predecessor position for |update_item|, based on its
428   // absolute server position.  The returned ID will be a valid predecessor
429   // under SERVER_PARENT_ID that is consistent with the
430   // SERVER_POSITION_IN_PARENT ordering.
431   Id ComputePrevIdFromServerPosition(const Id& parent_id) const;
432 
433   // Dumps all entry info into a DictionaryValue and returns it.
434   // Transfers ownership of the DictionaryValue to the caller.
435   DictionaryValue* ToValue() const;
436 
437  protected:  // Don't allow creation on heap, except by sync API wrappers.
438   friend class sync_api::ReadNode;
new(size_t size)439   void* operator new(size_t size) { return (::operator new)(size); }
440 
Entry(BaseTransaction * trans)441   inline Entry(BaseTransaction* trans)
442       : basetrans_(trans),
443         kernel_(NULL) { }
444 
445  protected:
446 
447   BaseTransaction* const basetrans_;
448 
449   EntryKernel* kernel_;
450 
451  private:
452   // Like GetServerModelType() but without the DCHECKs.
453   ModelType GetServerModelTypeHelper() const;
454 
455   DISALLOW_COPY_AND_ASSIGN(Entry);
456 };
457 
458 // A mutable meta entry.  Changes get committed to the database when the
459 // WriteTransaction is destroyed.
460 class MutableEntry : public Entry {
461   friend class WriteTransaction;
462   friend class Directory;
463   void Init(WriteTransaction* trans, const Id& parent_id,
464       const std::string& name);
465  public:
466   MutableEntry(WriteTransaction* trans, Create, const Id& parent_id,
467                const std::string& name);
468   MutableEntry(WriteTransaction* trans, CreateNewUpdateItem, const Id& id);
469   MutableEntry(WriteTransaction* trans, GetByHandle, int64);
470   MutableEntry(WriteTransaction* trans, GetById, const Id&);
471   MutableEntry(WriteTransaction* trans, GetByClientTag, const std::string& tag);
472   MutableEntry(WriteTransaction* trans, GetByServerTag, const std::string& tag);
473 
write_transaction()474   inline WriteTransaction* write_transaction() const {
475     return write_transaction_;
476   }
477 
478   // Field Accessors.  Some of them trigger the re-indexing of the entry.
479   // Return true on success, return false on failure, which means
480   // that putting the value would have caused a duplicate in the index.
481   // TODO(chron): Remove some of these unecessary return values.
482   bool Put(Int64Field field, const int64& value);
483   bool Put(IdField field, const Id& value);
484 
485   // Do a simple property-only update if the PARENT_ID field.  Use with caution.
486   //
487   // The normal Put(IS_PARENT) call will move the item to the front of the
488   // sibling order to maintain the linked list invariants when the parent
489   // changes.  That's usually what you want to do, but it's inappropriate
490   // when the caller is trying to change the parent ID of a the whole set
491   // of children (e.g. because the ID changed during a commit).  For those
492   // cases, there's this function.  It will corrupt the sibling ordering
493   // if you're not careful.
494   void PutParentIdPropertyOnly(const Id& parent_id);
495 
496   bool Put(StringField field, const std::string& value);
497   bool Put(BaseVersion field, int64 value);
498 
499   bool Put(ProtoField field, const sync_pb::EntitySpecifics& value);
500   bool Put(BitField field, bool value);
Put(IsDelField field,bool value)501   inline bool Put(IsDelField field, bool value) {
502     return PutIsDel(value);
503   }
504   bool Put(IndexedBitField field, bool value);
505 
506   // Sets the position of this item, and updates the entry kernels of the
507   // adjacent siblings so that list invariants are maintained.  Returns false
508   // and fails if |predecessor_id| does not identify a sibling.  Pass the root
509   // ID to put the node in first position.
510   bool PutPredecessor(const Id& predecessor_id);
511 
512   bool Put(BitTemp field, bool value);
513 
514  protected:
515   syncable::MetahandleSet* GetDirtyIndexHelper();
516 
517   bool PutIsDel(bool value);
518 
519  private:  // Don't allow creation on heap, except by sync API wrappers.
520   friend class sync_api::WriteNode;
new(size_t size)521   void* operator new(size_t size) { return (::operator new)(size); }
522 
523   bool PutImpl(StringField field, const std::string& value);
524   bool PutUniqueClientTag(const std::string& value);
525 
526   // Adjusts the successor and predecessor entries so that they no longer
527   // refer to this entry.
528   void UnlinkFromOrder();
529 
530   // Kind of redundant. We should reduce the number of pointers
531   // floating around if at all possible. Could we store this in Directory?
532   // Scope: Set on construction, never changed after that.
533   WriteTransaction* const write_transaction_;
534 
535  protected:
536   MutableEntry();
537 
538   DISALLOW_COPY_AND_ASSIGN(MutableEntry);
539 };
540 
541 class LessParentIdAndHandle;
542 template <typename FieldType, FieldType field_index>
543 class LessField;
544 class LessEntryMetaHandles {
545  public:
operator()546   inline bool operator()(const syncable::EntryKernel& a,
547                          const syncable::EntryKernel& b) const {
548     return a.ref(META_HANDLE) < b.ref(META_HANDLE);
549   }
550 };
551 typedef std::set<EntryKernel, LessEntryMetaHandles> OriginalEntries;
552 
553 // How syncable indices & Indexers work.
554 //
555 // The syncable Directory maintains several indices on the Entries it tracks.
556 // The indices follow a common pattern:
557 //   (a) The index allows efficient lookup of an Entry* with particular
558 //       field values.  This is done by use of a std::set<> and a custom
559 //       comparator.
560 //   (b) There may be conditions for inclusion in the index -- for example,
561 //       deleted items might not be indexed.
562 //   (c) Because the index set contains only Entry*, one must be careful
563 //       to remove Entries from the set before updating the value of
564 //       an indexed field.
565 // The traits of an index are a Comparator (to define the set ordering) and a
566 // ShouldInclude function (to define the conditions for inclusion).  For each
567 // index, the traits are grouped into a class called an Indexer which
568 // can be used as a template type parameter.
569 
570 // Traits type for metahandle index.
571 struct MetahandleIndexer {
572   // This index is of the metahandle field values.
573   typedef LessField<MetahandleField, META_HANDLE> Comparator;
574 
575   // This index includes all entries.
ShouldIncludeMetahandleIndexer576   inline static bool ShouldInclude(const EntryKernel* a) {
577     return true;
578   }
579 };
580 
581 // Traits type for ID field index.
582 struct IdIndexer {
583   // This index is of the ID field values.
584   typedef LessField<IdField, ID> Comparator;
585 
586   // This index includes all entries.
ShouldIncludeIdIndexer587   inline static bool ShouldInclude(const EntryKernel* a) {
588     return true;
589   }
590 };
591 
592 // Traits type for unique client tag index.
593 struct ClientTagIndexer {
594   // This index is of the client-tag values.
595   typedef LessField<StringField, UNIQUE_CLIENT_TAG> Comparator;
596 
597   // Items are only in this index if they have a non-empty client tag value.
598   static bool ShouldInclude(const EntryKernel* a);
599 };
600 
601 // This index contains EntryKernels ordered by parent ID and metahandle.
602 // It allows efficient lookup of the children of a given parent.
603 struct ParentIdAndHandleIndexer {
604   // This index is of the parent ID and metahandle.  We use a custom
605   // comparator.
606   class Comparator {
607    public:
608     bool operator() (const syncable::EntryKernel* a,
609                      const syncable::EntryKernel* b) const;
610   };
611 
612   // This index does not include deleted items.
613   static bool ShouldInclude(const EntryKernel* a);
614 };
615 
616 // Given an Indexer providing the semantics of an index, defines the
617 // set type used to actually contain the index.
618 template <typename Indexer>
619 struct Index {
620   typedef std::set<EntryKernel*, typename Indexer::Comparator> Set;
621 };
622 
623 // a WriteTransaction has a writer tag describing which body of code is doing
624 // the write. This is defined up here since DirectoryChangeEvent also contains
625 // one.
626 enum WriterTag {
627   INVALID,
628   SYNCER,
629   AUTHWATCHER,
630   UNITTEST,
631   VACUUM_AFTER_SAVE,
632   PURGE_ENTRIES,
633   SYNCAPI
634 };
635 
636 // The name Directory in this case means the entire directory
637 // structure within a single user account.
638 //
639 // Sqlite is a little goofy, in that each thread must access a database
640 // via its own handle.  So, a Directory object should only be accessed
641 // from a single thread.  Use DirectoryManager's Open() method to
642 // always get a directory that has been properly initialized on the
643 // current thread.
644 //
645 // The db is protected against concurrent modification by a reader/
646 // writer lock, negotiated by the ReadTransaction and WriteTransaction
647 // friend classes.  The in-memory indices are protected against
648 // concurrent modification by the kernel lock.
649 //
650 // All methods which require the reader/writer lock to be held either
651 //   are protected and only called from friends in a transaction
652 //   or are public and take a Transaction* argument.
653 //
654 // All methods which require the kernel lock to be already held take a
655 // ScopeKernelLock* argument.
656 //
657 // To prevent deadlock, the reader writer transaction lock must always
658 // be held before acquiring the kernel lock.
659 class ScopedKernelLock;
660 class IdFilter;
661 class DirectoryManager;
662 
663 class Directory {
664   friend class BaseTransaction;
665   friend class Entry;
666   friend class MutableEntry;
667   friend class ReadTransaction;
668   friend class ReadTransactionWithoutDB;
669   friend class ScopedKernelLock;
670   friend class ScopedKernelUnlock;
671   friend class WriteTransaction;
672   friend class SyncableDirectoryTest;
673   FRIEND_TEST_ALL_PREFIXES(SyncableDirectoryTest,
674                            TakeSnapshotGetsAllDirtyHandlesTest);
675   FRIEND_TEST_ALL_PREFIXES(SyncableDirectoryTest,
676                            TakeSnapshotGetsOnlyDirtyHandlesTest);
677   FRIEND_TEST_ALL_PREFIXES(SyncableDirectoryTest, TestPurgeEntriesWithTypeIn);
678   FRIEND_TEST_ALL_PREFIXES(SyncableDirectoryTest,
679                            TakeSnapshotGetsMetahandlesToPurge);
680 
681  public:
682   class EventListenerHookup;
683 
684   // Various data that the Directory::Kernel we are backing (persisting data
685   // for) needs saved across runs of the application.
686   struct PersistedKernelInfo {
687     AutofillMigrationDebugInfo autofill_migration_debug_info;
688 
689     PersistedKernelInfo();
690     ~PersistedKernelInfo();
691 
692     // Set the |download_progress| entry for the given model to a
693     // "first sync" start point.  When such a value is sent to the server,
694     // a full download of all objects of the model will be initiated.
695     void reset_download_progress(ModelType model_type);
696 
697     // Last sync timestamp fetched from the server.
698     sync_pb::DataTypeProgressMarker download_progress[MODEL_TYPE_COUNT];
699     // true iff we ever reached the end of the changelog.
700     ModelTypeBitSet initial_sync_ended;
701     // The store birthday we were given by the server. Contents are opaque to
702     // the client.
703     std::string store_birthday;
704     // The next local ID that has not been used with this cache-GUID.
705     int64 next_id;
706     // The persisted notification state.
707     std::string notification_state;
708 
709     AutofillMigrationState autofill_migration_state;
710   };
711 
712   // What the Directory needs on initialization to create itself and its Kernel.
713   // Filled by DirectoryBackingStore::Load.
714   struct KernelLoadInfo {
715     PersistedKernelInfo kernel_info;
716     std::string cache_guid;  // Created on first initialization, never changes.
717     int64 max_metahandle;    // Computed (using sql MAX aggregate) on init.
KernelLoadInfoKernelLoadInfo718     KernelLoadInfo() : max_metahandle(0) {
719     }
720   };
721 
722   // The dirty/clean state of kernel fields backed by the share_info table.
723   // This is public so it can be used in SaveChangesSnapshot for persistence.
724   enum KernelShareInfoStatus {
725     KERNEL_SHARE_INFO_INVALID,
726     KERNEL_SHARE_INFO_VALID,
727     KERNEL_SHARE_INFO_DIRTY
728   };
729 
730   // When the Directory is told to SaveChanges, a SaveChangesSnapshot is
731   // constructed and forms a consistent snapshot of what needs to be sent to
732   // the backing store.
733   struct SaveChangesSnapshot {
734     SaveChangesSnapshot();
735     ~SaveChangesSnapshot();
736 
737     KernelShareInfoStatus kernel_info_status;
738     PersistedKernelInfo kernel_info;
739     OriginalEntries dirty_metas;
740     MetahandleSet metahandles_to_purge;
741   };
742 
743   Directory();
744   virtual ~Directory();
745 
746   DirOpenResult Open(const FilePath& file_path, const std::string& name);
747 
748   void Close();
749 
750   int64 NextMetahandle();
751   // Always returns a negative id.  Positive client ids are generated
752   // by the server only.
753   Id NextId();
754 
file_path()755   const FilePath& file_path() const { return kernel_->db_path; }
good()756   bool good() const { return NULL != store_; }
757 
758   // The download progress is an opaque token provided by the sync server
759   // to indicate the continuation state of the next GetUpdates operation.
760   void GetDownloadProgress(
761       ModelType type,
762       sync_pb::DataTypeProgressMarker* value_out) const;
763   void GetDownloadProgressAsString(
764       ModelType type,
765       std::string* value_out) const;
766   void SetDownloadProgress(
767       ModelType type,
768       const sync_pb::DataTypeProgressMarker& value);
769 
770   bool initial_sync_ended_for_type(ModelType type) const;
771   void set_initial_sync_ended_for_type(ModelType type, bool value);
772   AutofillMigrationState get_autofill_migration_state() const;
773 
774   AutofillMigrationDebugInfo get_autofill_migration_debug_info() const;
775 
776   void set_autofill_migration_state(AutofillMigrationState state);
777 
778   void set_autofill_migration_state_debug_info(
779       syncable::AutofillMigrationDebugInfo::PropertyToSet property_to_set,
780       const syncable::AutofillMigrationDebugInfo& info);
781 
name()782   const std::string& name() const { return kernel_->name; }
783 
784   // (Account) Store birthday is opaque to the client, so we keep it in the
785   // format it is in the proto buffer in case we switch to a binary birthday
786   // later.
787   std::string store_birthday() const;
788   void set_store_birthday(const std::string& store_birthday);
789 
790   std::string GetAndClearNotificationState();
791   void SetNotificationState(const std::string& notification_state);
792 
793   // Unique to each account / client pair.
794   std::string cache_guid() const;
795 
796   void SetChangeListener(DirectoryChangeListener* listener);
797 
798  protected:  // for friends, mainly used by Entry constructors
799   virtual EntryKernel* GetEntryByHandle(int64 handle);
800   virtual EntryKernel* GetEntryByHandle(int64 metahandle,
801       ScopedKernelLock* lock);
802   virtual EntryKernel* GetEntryById(const Id& id);
803   EntryKernel* GetEntryByServerTag(const std::string& tag);
804   virtual EntryKernel* GetEntryByClientTag(const std::string& tag);
805   EntryKernel* GetRootEntry();
806   bool ReindexId(EntryKernel* const entry, const Id& new_id);
807   void ReindexParentId(EntryKernel* const entry, const Id& new_parent_id);
808   void ClearDirtyMetahandles();
809 
810   // These don't do semantic checking.
811   // The semantic checking is implemented higher up.
812   void UnlinkEntryFromOrder(EntryKernel* entry,
813                             WriteTransaction* trans,
814                             ScopedKernelLock* lock);
815 
816   // Overridden by tests.
817   virtual DirectoryBackingStore* CreateBackingStore(
818       const std::string& dir_name,
819       const FilePath& backing_filepath);
820 
821  private:
822   // These private versions expect the kernel lock to already be held
823   // before calling.
824   EntryKernel* GetEntryById(const Id& id, ScopedKernelLock* const lock);
825 
826   DirOpenResult OpenImpl(const FilePath& file_path, const std::string& name);
827 
828   template <class T> void TestAndSet(T* kernel_data, const T* data_to_set);
829 
830   struct DirectoryEventTraits {
831     typedef DirectoryEvent EventType;
IsChannelShutdownEventDirectoryEventTraits832     static inline bool IsChannelShutdownEvent(const DirectoryEvent& event) {
833       return DIRECTORY_DESTROYED == event;
834     }
835   };
836  public:
837   typedef EventChannel<DirectoryEventTraits, base::Lock> Channel;
838   typedef std::vector<int64> ChildHandles;
839 
840   // Returns the child meta handles for given parent id.
841   void GetChildHandles(BaseTransaction*, const Id& parent_id,
842       ChildHandles* result);
843 
844   // Find the first or last child in the positional ordering under a parent,
845   // and return its id.  Returns a root Id if parent has no children.
846   virtual Id GetFirstChildId(BaseTransaction* trans, const Id& parent_id);
847   Id GetLastChildId(BaseTransaction* trans, const Id& parent_id);
848 
849   // Compute a local predecessor position for |update_item|.  The position
850   // is determined by the SERVER_POSITION_IN_PARENT value of |update_item|,
851   // as well as the SERVER_POSITION_IN_PARENT values of any up-to-date
852   // children of |parent_id|.
853   Id ComputePrevIdFromServerPosition(
854       const EntryKernel* update_item,
855       const syncable::Id& parent_id);
856 
857   // SaveChanges works by taking a consistent snapshot of the current Directory
858   // state and indices (by deep copy) under a ReadTransaction, passing this
859   // snapshot to the backing store under no transaction, and finally cleaning
860   // up by either purging entries no longer needed (this part done under a
861   // WriteTransaction) or rolling back the dirty bits.  It also uses
862   // internal locking to enforce SaveChanges operations are mutually exclusive.
863   //
864   // WARNING: THIS METHOD PERFORMS SYNCHRONOUS I/O VIA SQLITE.
865   bool SaveChanges();
866 
867   // Returns the number of entities with the unsynced bit set.
868   int64 unsynced_entity_count() const;
869 
870   // Get GetUnsyncedMetaHandles should only be called after SaveChanges and
871   // before any new entries have been created. The intention is that the
872   // syncer should call it from its PerformSyncQueries member.
873   typedef std::vector<int64> UnsyncedMetaHandles;
874   void GetUnsyncedMetaHandles(BaseTransaction* trans,
875                               UnsyncedMetaHandles* result);
876 
877   // Get all the metahandles for unapplied updates
878   typedef std::vector<int64> UnappliedUpdateMetaHandles;
879   void GetUnappliedUpdateMetaHandles(BaseTransaction* trans,
880                                      UnappliedUpdateMetaHandles* result);
881 
882   // Get the channel for post save notification, used by the syncer.
channel()883   inline Channel* channel() const {
884     return kernel_->channel;
885   }
886 
887   // Checks tree metadata consistency.
888   // If full_scan is false, the function will avoid pulling any entries from the
889   // db and scan entries currently in ram.
890   // If full_scan is true, all entries will be pulled from the database.
891   // No return value, CHECKs will be triggered if we're given bad
892   // information.
893   void CheckTreeInvariants(syncable::BaseTransaction* trans,
894                            bool full_scan);
895 
896   void CheckTreeInvariants(syncable::BaseTransaction* trans,
897                            const OriginalEntries* originals);
898 
899   void CheckTreeInvariants(syncable::BaseTransaction* trans,
900                            const MetahandleSet& handles,
901                            const IdFilter& idfilter);
902 
903   // Purges all data associated with any entries whose ModelType or
904   // ServerModelType is found in |types|, from _both_ memory and disk.
905   // Only  valid, "real" model types are allowed in |types| (see model_type.h
906   // for definitions).  "Purge" is just meant to distinguish from "deleting"
907   // entries, which means something different in the syncable namespace.
908   // WARNING! This can be real slow, as it iterates over all entries.
909   // WARNING! Performs synchronous I/O.
910   virtual void PurgeEntriesWithTypeIn(const std::set<ModelType>& types);
911 
912  private:
913   // Helper to prime ids_index, parent_id_and_names_index, unsynced_metahandles
914   // and unapplied_metahandles from metahandles_index.
915   void InitializeIndices();
916 
917   // Constructs a consistent snapshot of the current Directory state and
918   // indices (by deep copy) under a ReadTransaction for use in |snapshot|.
919   // See SaveChanges() for more information.
920   void TakeSnapshotForSaveChanges(SaveChangesSnapshot* snapshot);
921 
922   // Purges from memory any unused, safe to remove entries that were
923   // successfully deleted on disk as a result of the SaveChanges that processed
924   // |snapshot|.  See SaveChanges() for more information.
925   void VacuumAfterSaveChanges(const SaveChangesSnapshot& snapshot);
926 
927   // Rolls back dirty bits in the event that the SaveChanges that
928   // processed |snapshot| failed, for example, due to no disk space.
929   void HandleSaveChangesFailure(const SaveChangesSnapshot& snapshot);
930 
931   // For new entry creation only
932   void InsertEntry(EntryKernel* entry, ScopedKernelLock* lock);
933   void InsertEntry(EntryKernel* entry);
934 
935   // Used by CheckTreeInvariants
936   void GetAllMetaHandles(BaseTransaction* trans, MetahandleSet* result);
937   bool SafeToPurgeFromMemory(const EntryKernel* const entry) const;
938 
939   // Internal setters that do not acquire a lock internally.  These are unsafe
940   // on their own; caller must guarantee exclusive access manually by holding
941   // a ScopedKernelLock.
942   void set_initial_sync_ended_for_type_unsafe(ModelType type, bool x);
943   void SetNotificationStateUnsafe(const std::string& notification_state);
944 
945   Directory& operator = (const Directory&);
946 
947  public:
948   typedef Index<MetahandleIndexer>::Set MetahandlesIndex;
949   typedef Index<IdIndexer>::Set IdsIndex;
950   // All entries in memory must be in both the MetahandlesIndex and
951   // the IdsIndex, but only non-deleted entries will be the
952   // ParentIdChildIndex.
953   typedef Index<ParentIdAndHandleIndexer>::Set ParentIdChildIndex;
954 
955   // Contains both deleted and existing entries with tags.
956   // We can't store only existing tags because the client would create
957   // items that had a duplicated ID in the end, resulting in a DB key
958   // violation. ID reassociation would fail after an attempted commit.
959   typedef Index<ClientTagIndexer>::Set ClientTagIndex;
960 
961  protected:
962   // Used by tests.
963   void init_kernel(const std::string& name);
964 
965  private:
966 
967   struct Kernel {
968     Kernel(const FilePath& db_path, const std::string& name,
969            const KernelLoadInfo& info);
970 
971     ~Kernel();
972 
973     void AddRef();  // For convenience.
974     void Release();
975 
976     FilePath const db_path;
977     // TODO(timsteele): audit use of the member and remove if possible
978     volatile base::subtle::AtomicWord refcount;
979 
980     // Implements ReadTransaction / WriteTransaction using a simple lock.
981     base::Lock transaction_mutex;
982 
983     // The name of this directory.
984     std::string const name;
985 
986     // Protects all members below.
987     // The mutex effectively protects all the indices, but not the
988     // entries themselves.  So once a pointer to an entry is pulled
989     // from the index, the mutex can be unlocked and entry read or written.
990     //
991     // Never hold the mutex and do anything with the database or any
992     // other buffered IO.  Violating this rule will result in deadlock.
993     base::Lock mutex;
994     // Entries indexed by metahandle
995     MetahandlesIndex* metahandles_index;
996     // Entries indexed by id
997     IdsIndex* ids_index;
998     ParentIdChildIndex* parent_id_child_index;
999     ClientTagIndex* client_tag_index;
1000     // So we don't have to create an EntryKernel every time we want to
1001     // look something up in an index.  Needle in haystack metaphor.
1002     EntryKernel needle;
1003 
1004     // 3 in-memory indices on bits used extremely frequently by the syncer.
1005     MetahandleSet* const unapplied_update_metahandles;
1006     MetahandleSet* const unsynced_metahandles;
1007     // Contains metahandles that are most likely dirty (though not
1008     // necessarily).  Dirtyness is confirmed in TakeSnapshotForSaveChanges().
1009     MetahandleSet* const dirty_metahandles;
1010 
1011     // When a purge takes place, we remove items from all our indices and stash
1012     // them in here so that SaveChanges can persist their permanent deletion.
1013     MetahandleSet* const metahandles_to_purge;
1014 
1015     // TODO(ncarter): Figure out what the hell this is, and comment it.
1016     Channel* const channel;
1017 
1018     // The listener for directory change events, triggered when the transaction
1019     // is ending.
1020     DirectoryChangeListener* change_listener_;
1021 
1022     KernelShareInfoStatus info_status;
1023 
1024     // These 3 members are backed in the share_info table, and
1025     // their state is marked by the flag above.
1026 
1027     // A structure containing the Directory state that is written back into the
1028     // database on SaveChanges.
1029     PersistedKernelInfo persisted_info;
1030 
1031     // A unique identifier for this account's cache db, used to generate
1032     // unique server IDs. No need to lock, only written at init time.
1033     std::string cache_guid;
1034 
1035     // It doesn't make sense for two threads to run SaveChanges at the same
1036     // time; this mutex protects that activity.
1037     base::Lock save_changes_mutex;
1038 
1039     // The next metahandle is protected by kernel mutex.
1040     int64 next_metahandle;
1041 
1042     // Keep a history of recently flushed metahandles for debugging
1043     // purposes.  Protected by the save_changes_mutex.
1044     DebugQueue<int64, 1000> flushed_metahandles;
1045   };
1046 
1047   // Helper method used to do searches on |parent_id_child_index|.
1048   ParentIdChildIndex::iterator LocateInParentChildIndex(
1049       const ScopedKernelLock& lock,
1050       const Id& parent_id,
1051       int64 position_in_parent,
1052       const Id& item_id_for_tiebreaking);
1053 
1054   // Return an iterator to the beginning of the range of the children of
1055   // |parent_id| in the kernel's parent_id_child_index.
1056   ParentIdChildIndex::iterator GetParentChildIndexLowerBound(
1057       const ScopedKernelLock& lock,
1058       const Id& parent_id);
1059 
1060   // Return an iterator to just past the end of the range of the
1061   // children of |parent_id| in the kernel's parent_id_child_index.
1062   ParentIdChildIndex::iterator GetParentChildIndexUpperBound(
1063       const ScopedKernelLock& lock,
1064       const Id& parent_id);
1065 
1066   Kernel* kernel_;
1067 
1068   DirectoryBackingStore* store_;
1069 };
1070 
1071 class ScopedKernelLock {
1072  public:
1073   explicit ScopedKernelLock(const Directory*);
~ScopedKernelLock()1074   ~ScopedKernelLock() {}
1075 
1076   base::AutoLock scoped_lock_;
1077   Directory* const dir_;
1078   DISALLOW_COPY_AND_ASSIGN(ScopedKernelLock);
1079 };
1080 
1081 // Transactions are now processed FIFO with a straight lock
1082 class BaseTransaction {
1083   friend class Entry;
1084  public:
directory()1085   inline Directory* directory() const { return directory_; }
root_id()1086   inline Id root_id() const { return Id(); }
1087 
1088   virtual ~BaseTransaction();
1089 
1090  protected:
1091   BaseTransaction(Directory* directory, const char* name,
1092                   const char* source_file, int line, WriterTag writer);
1093 
1094   // For unit testing. Everything will be mocked out no point initializing.
1095   explicit BaseTransaction(Directory* directory);
1096 
1097   void UnlockAndLog(OriginalEntries* entries);
1098   virtual bool NotifyTransactionChangingAndEnding(
1099       OriginalEntries* entries,
1100       ModelTypeBitSet* models_with_changes);
1101   virtual void NotifyTransactionComplete(ModelTypeBitSet models_with_changes);
1102 
1103   Directory* const directory_;
1104   Directory::Kernel* const dirkernel_;  // for brevity
1105   const char* const name_;
1106   base::TimeTicks time_acquired_;
1107   const char* const source_file_;
1108   const int line_;
1109   WriterTag writer_;
1110 
1111  private:
1112   void Lock();
1113 
1114   DISALLOW_COPY_AND_ASSIGN(BaseTransaction);
1115 };
1116 
1117 // Locks db in constructor, unlocks in destructor.
1118 class ReadTransaction : public BaseTransaction {
1119  public:
1120   ReadTransaction(Directory* directory, const char* source_file,
1121                   int line);
1122   ReadTransaction(const ScopedDirLookup& scoped_dir,
1123                   const char* source_file, int line);
1124 
1125   virtual ~ReadTransaction();
1126 
1127  protected:  // Don't allow creation on heap, except by sync API wrapper.
1128   friend class sync_api::ReadTransaction;
new(size_t size)1129   void* operator new(size_t size) { return (::operator new)(size); }
1130 
1131   DISALLOW_COPY_AND_ASSIGN(ReadTransaction);
1132 };
1133 
1134 // Locks db in constructor, unlocks in destructor.
1135 class WriteTransaction : public BaseTransaction {
1136   friend class MutableEntry;
1137  public:
1138   explicit WriteTransaction(Directory* directory, WriterTag writer,
1139                             const char* source_file, int line);
1140   explicit WriteTransaction(const ScopedDirLookup& directory,
1141                             WriterTag writer, const char* source_file,
1142                             int line);
1143   virtual ~WriteTransaction();
1144 
1145   void SaveOriginal(EntryKernel* entry);
1146 
1147  protected:
1148   // Before an entry gets modified, we copy the original into a list
1149   // so that we can issue change notifications when the transaction
1150   // is done.
1151   OriginalEntries* const originals_;
1152 
1153   explicit WriteTransaction(Directory *directory);
1154 
1155   DISALLOW_COPY_AND_ASSIGN(WriteTransaction);
1156 };
1157 
1158 bool IsLegalNewParent(BaseTransaction* trans, const Id& id, const Id& parentid);
1159 
1160 int64 Now();
1161 
1162 // This function sets only the flags needed to get this entry to sync.
1163 void MarkForSyncing(syncable::MutableEntry* e);
1164 
1165 // This is not a reset.  It just sets the numeric fields which are not
1166 // initialized by the constructor to zero.
1167 void ZeroFields(EntryKernel* entry, int first_field);
1168 
1169 }  // namespace syncable
1170 
1171 std::ostream& operator <<(std::ostream&, const syncable::Blob&);
1172 
1173 #endif  // CHROME_BROWSER_SYNC_SYNCABLE_SYNCABLE_H_
1174