| OLD | NEW |
| (Empty) |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef SYNC_SYNCABLE_DIRECTORY_H_ | |
| 6 #define SYNC_SYNCABLE_DIRECTORY_H_ | |
| 7 | |
| 8 #include <stddef.h> | |
| 9 #include <stdint.h> | |
| 10 | |
| 11 #include <deque> | |
| 12 #include <set> | |
| 13 #include <string> | |
| 14 #include <unordered_map> | |
| 15 #include <vector> | |
| 16 | |
| 17 #include "base/callback.h" | |
| 18 #include "base/containers/hash_tables.h" | |
| 19 #include "base/files/file_util.h" | |
| 20 #include "base/gtest_prod_util.h" | |
| 21 #include "base/macros.h" | |
| 22 #include "base/values.h" | |
| 23 #include "sync/api/attachments/attachment_id.h" | |
| 24 #include "sync/base/sync_export.h" | |
| 25 #include "sync/internal_api/public/util/weak_handle.h" | |
| 26 #include "sync/syncable/dir_open_result.h" | |
| 27 #include "sync/syncable/entry.h" | |
| 28 #include "sync/syncable/entry_kernel.h" | |
| 29 #include "sync/syncable/metahandle_set.h" | |
| 30 #include "sync/syncable/parent_child_index.h" | |
| 31 #include "sync/syncable/syncable_delete_journal.h" | |
| 32 | |
| 33 namespace syncer { | |
| 34 | |
| 35 class Cryptographer; | |
| 36 class TestUserShare; | |
| 37 class UnrecoverableErrorHandler; | |
| 38 | |
| 39 namespace syncable { | |
| 40 | |
| 41 class BaseTransaction; | |
| 42 class BaseWriteTransaction; | |
| 43 class DirectoryChangeDelegate; | |
| 44 class DirectoryBackingStore; | |
| 45 class NigoriHandler; | |
| 46 class ScopedKernelLock; | |
| 47 class TransactionObserver; | |
| 48 class WriteTransaction; | |
| 49 | |
| 50 enum InvariantCheckLevel { | |
| 51 OFF = 0, // No checking. | |
| 52 VERIFY_CHANGES = 1, // Checks only mutated entries. Does not check | |
| 53 // hierarchy. | |
| 54 FULL_DB_VERIFICATION = 2 // Check every entry. This can be expensive. | |
| 55 }; | |
| 56 | |
| 57 // Directory stores and manages EntryKernels. | |
| 58 // | |
| 59 // This class is tightly coupled to several other classes via Directory::Kernel. | |
| 60 // Although Directory's kernel_ is exposed via public accessor it should be | |
| 61 // treated as pseudo-private. | |
| 62 class SYNC_EXPORT Directory { | |
| 63 public: | |
| 64 typedef std::vector<int64_t> Metahandles; | |
| 65 | |
| 66 typedef std::unordered_map<int64_t, EntryKernel*> MetahandlesMap; | |
| 67 typedef std::unordered_map<std::string, EntryKernel*> IdsMap; | |
| 68 typedef std::unordered_map<std::string, EntryKernel*> TagsMap; | |
| 69 typedef std::string AttachmentIdUniqueId; | |
| 70 typedef std::unordered_map<AttachmentIdUniqueId, MetahandleSet> | |
| 71 IndexByAttachmentId; | |
| 72 | |
| 73 static const base::FilePath::CharType kSyncDatabaseFilename[]; | |
| 74 | |
| 75 // The dirty/clean state of kernel fields backed by the share_info table. | |
| 76 // This is public so it can be used in SaveChangesSnapshot for persistence. | |
| 77 enum KernelShareInfoStatus { | |
| 78 KERNEL_SHARE_INFO_INVALID, | |
| 79 KERNEL_SHARE_INFO_VALID, | |
| 80 KERNEL_SHARE_INFO_DIRTY | |
| 81 }; | |
| 82 | |
| 83 // Various data that the Directory::Kernel we are backing (persisting data | |
| 84 // for) needs saved across runs of the application. | |
| 85 struct SYNC_EXPORT PersistedKernelInfo { | |
| 86 PersistedKernelInfo(); | |
| 87 ~PersistedKernelInfo(); | |
| 88 | |
| 89 // Set the |download_progress| entry for the given model to a | |
| 90 // "first sync" start point. When such a value is sent to the server, | |
| 91 // a full download of all objects of the model will be initiated. | |
| 92 void ResetDownloadProgress(ModelType model_type); | |
| 93 | |
| 94 // Whether a valid progress marker exists for |model_type|. | |
| 95 bool HasEmptyDownloadProgress(ModelType model_type); | |
| 96 | |
| 97 // Last sync timestamp fetched from the server. | |
| 98 sync_pb::DataTypeProgressMarker download_progress[MODEL_TYPE_COUNT]; | |
| 99 // Sync-side transaction version per data type. Monotonically incremented | |
| 100 // when updating native model. A copy is also saved in native model. | |
| 101 // Later out-of-sync models can be detected and fixed by comparing | |
| 102 // transaction versions of sync model and native model. | |
| 103 // TODO(hatiaol): implement detection and fixing of out-of-sync models. | |
| 104 // Bug 154858. | |
| 105 int64_t transaction_version[MODEL_TYPE_COUNT]; | |
| 106 // The store birthday we were given by the server. Contents are opaque to | |
| 107 // the client. | |
| 108 std::string store_birthday; | |
| 109 // The serialized bag of chips we were given by the server. Contents are | |
| 110 // opaque to the client. This is the serialization of a message of type | |
| 111 // ChipBag defined in sync.proto. It can contains NULL characters. | |
| 112 std::string bag_of_chips; | |
| 113 // The per-datatype context. | |
| 114 sync_pb::DataTypeContext datatype_context[MODEL_TYPE_COUNT]; | |
| 115 }; | |
| 116 | |
| 117 // What the Directory needs on initialization to create itself and its Kernel. | |
| 118 // Filled by DirectoryBackingStore::Load. | |
| 119 struct KernelLoadInfo { | |
| 120 PersistedKernelInfo kernel_info; | |
| 121 std::string cache_guid; // Created on first initialization, never changes. | |
| 122 int64_t max_metahandle; // Computed (using sql MAX aggregate) on init. | |
| 123 KernelLoadInfo() : max_metahandle(0) { | |
| 124 } | |
| 125 }; | |
| 126 | |
| 127 // When the Directory is told to SaveChanges, a SaveChangesSnapshot is | |
| 128 // constructed and forms a consistent snapshot of what needs to be sent to | |
| 129 // the backing store. | |
| 130 struct SYNC_EXPORT SaveChangesSnapshot { | |
| 131 SaveChangesSnapshot(); | |
| 132 ~SaveChangesSnapshot(); | |
| 133 | |
| 134 // Returns true if this snapshot has any unsaved metahandle changes. | |
| 135 bool HasUnsavedMetahandleChanges() const; | |
| 136 | |
| 137 KernelShareInfoStatus kernel_info_status; | |
| 138 PersistedKernelInfo kernel_info; | |
| 139 EntryKernelSet dirty_metas; | |
| 140 MetahandleSet metahandles_to_purge; | |
| 141 EntryKernelSet delete_journals; | |
| 142 MetahandleSet delete_journals_to_purge; | |
| 143 }; | |
| 144 | |
| 145 struct Kernel { | |
| 146 // |delegate| must not be NULL. |transaction_observer| must be | |
| 147 // initialized. | |
| 148 Kernel(const std::string& name, const KernelLoadInfo& info, | |
| 149 DirectoryChangeDelegate* delegate, | |
| 150 const WeakHandle<TransactionObserver>& transaction_observer); | |
| 151 | |
| 152 ~Kernel(); | |
| 153 | |
| 154 // Implements ReadTransaction / WriteTransaction using a simple lock. | |
| 155 base::Lock transaction_mutex; | |
| 156 | |
| 157 // Protected by transaction_mutex. Used by WriteTransactions. | |
| 158 int64_t next_write_transaction_id; | |
| 159 | |
| 160 // The name of this directory. | |
| 161 std::string const name; | |
| 162 | |
| 163 // Protects all members below. | |
| 164 // The mutex effectively protects all the indices, but not the | |
| 165 // entries themselves. So once a pointer to an entry is pulled | |
| 166 // from the index, the mutex can be unlocked and entry read or written. | |
| 167 // | |
| 168 // Never hold the mutex and do anything with the database or any | |
| 169 // other buffered IO. Violating this rule will result in deadlock. | |
| 170 mutable base::Lock mutex; | |
| 171 | |
| 172 // Entries indexed by metahandle. This container is considered to be the | |
| 173 // owner of all EntryKernels, which may be referened by the other | |
| 174 // containers. If you remove an EntryKernel from this map, you probably | |
| 175 // want to remove it from all other containers and delete it, too. | |
| 176 MetahandlesMap metahandles_map; | |
| 177 | |
| 178 // Entries indexed by id | |
| 179 IdsMap ids_map; | |
| 180 | |
| 181 // Entries indexed by server tag. | |
| 182 // This map does not include any entries with non-existent server tags. | |
| 183 TagsMap server_tags_map; | |
| 184 | |
| 185 // Entries indexed by client tag. | |
| 186 // This map does not include any entries with non-existent client tags. | |
| 187 // IS_DEL items are included. | |
| 188 TagsMap client_tags_map; | |
| 189 | |
| 190 // Contains non-deleted items, indexed according to parent and position | |
| 191 // within parent. Protected by the ScopedKernelLock. | |
| 192 ParentChildIndex parent_child_index; | |
| 193 | |
| 194 // This index keeps track of which metahandles refer to a given attachment. | |
| 195 // Think of it as the inverse of EntryKernel's AttachmentMetadata Records. | |
| 196 // | |
| 197 // Because entries can be undeleted (e.g. PutIsDel(false)), entries should | |
| 198 // not removed from the index until they are actually deleted from memory. | |
| 199 // | |
| 200 // All access should go through IsAttachmentLinked, | |
| 201 // RemoveFromAttachmentIndex, AddToAttachmentIndex, and | |
| 202 // UpdateAttachmentIndex methods to avoid iterator invalidation errors. | |
| 203 IndexByAttachmentId index_by_attachment_id; | |
| 204 | |
| 205 // 3 in-memory indices on bits used extremely frequently by the syncer. | |
| 206 // |unapplied_update_metahandles| is keyed by the server model type. | |
| 207 MetahandleSet unapplied_update_metahandles[MODEL_TYPE_COUNT]; | |
| 208 MetahandleSet unsynced_metahandles; | |
| 209 // Contains metahandles that are most likely dirty (though not | |
| 210 // necessarily). Dirtyness is confirmed in TakeSnapshotForSaveChanges(). | |
| 211 MetahandleSet dirty_metahandles; | |
| 212 | |
| 213 // When a purge takes place, we remove items from all our indices and stash | |
| 214 // them in here so that SaveChanges can persist their permanent deletion. | |
| 215 MetahandleSet metahandles_to_purge; | |
| 216 | |
| 217 KernelShareInfoStatus info_status; | |
| 218 | |
| 219 // These 3 members are backed in the share_info table, and | |
| 220 // their state is marked by the flag above. | |
| 221 | |
| 222 // A structure containing the Directory state that is written back into the | |
| 223 // database on SaveChanges. | |
| 224 PersistedKernelInfo persisted_info; | |
| 225 | |
| 226 // A unique identifier for this account's cache db, used to generate | |
| 227 // unique server IDs. No need to lock, only written at init time. | |
| 228 const std::string cache_guid; | |
| 229 | |
| 230 // It doesn't make sense for two threads to run SaveChanges at the same | |
| 231 // time; this mutex protects that activity. | |
| 232 base::Lock save_changes_mutex; | |
| 233 | |
| 234 // The next metahandle is protected by kernel mutex. | |
| 235 int64_t next_metahandle; | |
| 236 | |
| 237 // The delegate for directory change events. Must not be NULL. | |
| 238 DirectoryChangeDelegate* const delegate; | |
| 239 | |
| 240 // The transaction observer. | |
| 241 const WeakHandle<TransactionObserver> transaction_observer; | |
| 242 }; | |
| 243 | |
| 244 // Does not take ownership of |encryptor|. | |
| 245 // |report_unrecoverable_error_function| may be NULL. | |
| 246 // Takes ownership of |store|. | |
| 247 Directory( | |
| 248 DirectoryBackingStore* store, | |
| 249 const WeakHandle<UnrecoverableErrorHandler>& unrecoverable_error_handler, | |
| 250 const base::Closure& report_unrecoverable_error_function, | |
| 251 NigoriHandler* nigori_handler, | |
| 252 Cryptographer* cryptographer); | |
| 253 virtual ~Directory(); | |
| 254 | |
| 255 // Does not take ownership of |delegate|, which must not be NULL. | |
| 256 // Starts sending events to |delegate| if the returned result is | |
| 257 // OPENED. Note that events to |delegate| may be sent from *any* | |
| 258 // thread. |transaction_observer| must be initialized. | |
| 259 DirOpenResult Open(const std::string& name, | |
| 260 DirectoryChangeDelegate* delegate, | |
| 261 const WeakHandle<TransactionObserver>& | |
| 262 transaction_observer); | |
| 263 | |
| 264 int64_t NextMetahandle(); | |
| 265 // Generates next client ID based on a randomly generated GUID. | |
| 266 syncable::Id NextId(); | |
| 267 | |
| 268 bool good() const { return NULL != kernel_; } | |
| 269 | |
| 270 // The download progress is an opaque token provided by the sync server | |
| 271 // to indicate the continuation state of the next GetUpdates operation. | |
| 272 void GetDownloadProgress( | |
| 273 ModelType type, | |
| 274 sync_pb::DataTypeProgressMarker* value_out) const; | |
| 275 void GetDownloadProgressAsString( | |
| 276 ModelType type, | |
| 277 std::string* value_out) const; | |
| 278 void SetDownloadProgress( | |
| 279 ModelType type, | |
| 280 const sync_pb::DataTypeProgressMarker& value); | |
| 281 bool HasEmptyDownloadProgress(ModelType type) const; | |
| 282 | |
| 283 // Gets the total number of entries in the directory. | |
| 284 size_t GetEntriesCount() const; | |
| 285 | |
| 286 // Gets/Increments transaction version of a model type. Must be called when | |
| 287 // holding kernel mutex. | |
| 288 int64_t GetTransactionVersion(ModelType type) const; | |
| 289 void IncrementTransactionVersion(ModelType type); | |
| 290 | |
| 291 // Getter/setters for the per datatype context. | |
| 292 void GetDataTypeContext(BaseTransaction* trans, | |
| 293 ModelType type, | |
| 294 sync_pb::DataTypeContext* context) const; | |
| 295 void SetDataTypeContext(BaseWriteTransaction* trans, | |
| 296 ModelType type, | |
| 297 const sync_pb::DataTypeContext& context); | |
| 298 | |
| 299 // Returns types for which the initial sync has ended. | |
| 300 ModelTypeSet InitialSyncEndedTypes(); | |
| 301 | |
| 302 // Returns true if the initial sync for |type| has completed. | |
| 303 bool InitialSyncEndedForType(ModelType type); | |
| 304 bool InitialSyncEndedForType(BaseTransaction* trans, ModelType type); | |
| 305 | |
| 306 // Marks the |type| as having its intial sync complete. | |
| 307 // This applies only to types with implicitly created root folders. | |
| 308 void MarkInitialSyncEndedForType(BaseWriteTransaction* trans, ModelType type); | |
| 309 | |
| 310 // (Account) Store birthday is opaque to the client, so we keep it in the | |
| 311 // format it is in the proto buffer in case we switch to a binary birthday | |
| 312 // later. | |
| 313 std::string store_birthday() const; | |
| 314 void set_store_birthday(const std::string& store_birthday); | |
| 315 | |
| 316 // (Account) Bag of chip is an opaque state used by the server to track the | |
| 317 // client. | |
| 318 std::string bag_of_chips() const; | |
| 319 void set_bag_of_chips(const std::string& bag_of_chips); | |
| 320 | |
| 321 // Unique to each account / client pair. | |
| 322 std::string cache_guid() const; | |
| 323 | |
| 324 // Returns a pointer to our Nigori node handler. | |
| 325 NigoriHandler* GetNigoriHandler(); | |
| 326 | |
| 327 // Returns a pointer to our cryptographer. Does not transfer ownership. | |
| 328 // Not thread safe, so should only be accessed while holding a transaction. | |
| 329 Cryptographer* GetCryptographer(const BaseTransaction* trans); | |
| 330 | |
| 331 // Called to immediately report an unrecoverable error (but don't | |
| 332 // propagate it up). | |
| 333 void ReportUnrecoverableError(); | |
| 334 | |
| 335 // Called to set the unrecoverable error on the directory and to propagate | |
| 336 // the error to upper layers. | |
| 337 void OnUnrecoverableError(const BaseTransaction* trans, | |
| 338 const tracked_objects::Location& location, | |
| 339 const std::string & message); | |
| 340 | |
| 341 DeleteJournal* delete_journal(); | |
| 342 | |
| 343 // Returns the child meta handles (even those for deleted/unlinked | |
| 344 // nodes) for given parent id. Clears |result| if there are no | |
| 345 // children. | |
| 346 bool GetChildHandlesById(BaseTransaction*, const Id& parent_id, | |
| 347 Metahandles* result); | |
| 348 | |
| 349 // Counts all items under the given node, including the node itself. | |
| 350 int GetTotalNodeCount(BaseTransaction*, EntryKernel* kernel_) const; | |
| 351 | |
| 352 // Returns this item's position within its parent folder. | |
| 353 // The left-most item is 0, second left-most is 1, etc. | |
| 354 int GetPositionIndex(BaseTransaction*, EntryKernel* kernel_) const; | |
| 355 | |
| 356 // Returns true iff |id| has children. | |
| 357 bool HasChildren(BaseTransaction* trans, const Id& id); | |
| 358 | |
| 359 // Find the first child in the positional ordering under a parent, | |
| 360 // and fill in |*first_child_id| with its id. Fills in a root Id if | |
| 361 // parent has no children. Returns true if the first child was | |
| 362 // successfully found, or false if an error was encountered. | |
| 363 Id GetFirstChildId(BaseTransaction* trans, const EntryKernel* parent); | |
| 364 | |
| 365 // These functions allow one to fetch the next or previous item under | |
| 366 // the same folder. Returns the "root" ID if there is no predecessor | |
| 367 // or successor. | |
| 368 // | |
| 369 // TODO(rlarocque): These functions are used mainly for tree traversal. We | |
| 370 // should replace these with an iterator API. See crbug.com/178275. | |
| 371 syncable::Id GetPredecessorId(EntryKernel* e); | |
| 372 syncable::Id GetSuccessorId(EntryKernel* e); | |
| 373 | |
| 374 // Places |e| as a successor to |predecessor|. If |predecessor| is NULL, | |
| 375 // |e| will be placed as the left-most item in its folder. | |
| 376 // | |
| 377 // Both |e| and |predecessor| must be valid entries under the same parent. | |
| 378 // | |
| 379 // TODO(rlarocque): This function includes limited support for placing items | |
| 380 // with valid positions (ie. Bookmarks) as siblings of items that have no set | |
| 381 // ordering (ie. Autofill items). This support is required only for tests, | |
| 382 // and should be removed. See crbug.com/178282. | |
| 383 void PutPredecessor(EntryKernel* e, EntryKernel* predecessor); | |
| 384 | |
| 385 // SaveChanges works by taking a consistent snapshot of the current Directory | |
| 386 // state and indices (by deep copy) under a ReadTransaction, passing this | |
| 387 // snapshot to the backing store under no transaction, and finally cleaning | |
| 388 // up by either purging entries no longer needed (this part done under a | |
| 389 // WriteTransaction) or rolling back the dirty bits. It also uses | |
| 390 // internal locking to enforce SaveChanges operations are mutually exclusive. | |
| 391 // | |
| 392 // WARNING: THIS METHOD PERFORMS SYNCHRONOUS I/O VIA SQLITE. | |
| 393 bool SaveChanges(); | |
| 394 | |
| 395 // Returns the number of entities with the unsynced bit set. | |
| 396 int64_t unsynced_entity_count() const; | |
| 397 | |
| 398 // Get GetUnsyncedMetaHandles should only be called after SaveChanges and | |
| 399 // before any new entries have been created. The intention is that the | |
| 400 // syncer should call it from its PerformSyncQueries member. | |
| 401 void GetUnsyncedMetaHandles(BaseTransaction* trans, | |
| 402 Metahandles* result); | |
| 403 | |
| 404 // Returns whether or not this |type| has unapplied updates. | |
| 405 bool TypeHasUnappliedUpdates(ModelType type); | |
| 406 | |
| 407 // Get all the metahandles for unapplied updates for a given set of | |
| 408 // server types. | |
| 409 void GetUnappliedUpdateMetaHandles(BaseTransaction* trans, | |
| 410 FullModelTypeSet server_types, | |
| 411 std::vector<int64_t>* result); | |
| 412 | |
| 413 // Get all the metahandles of entries of |type|. | |
| 414 void GetMetaHandlesOfType(BaseTransaction* trans, | |
| 415 ModelType type, | |
| 416 Metahandles* result); | |
| 417 | |
| 418 // Get metahandle counts for various criteria to show on the | |
| 419 // about:sync page. The information is computed on the fly | |
| 420 // each time. If this results in a significant performance hit, | |
| 421 // additional data structures can be added to cache results. | |
| 422 void CollectMetaHandleCounts(std::vector<int>* num_entries_by_type, | |
| 423 std::vector<int>* num_to_delete_entries_by_type); | |
| 424 | |
| 425 // Returns a ListValue serialization of all nodes for the given type. | |
| 426 std::unique_ptr<base::ListValue> GetNodeDetailsForType(BaseTransaction* trans, | |
| 427 ModelType type); | |
| 428 | |
| 429 // Sets the level of invariant checking performed after transactions. | |
| 430 void SetInvariantCheckLevel(InvariantCheckLevel check_level); | |
| 431 | |
| 432 // Checks tree metadata consistency following a transaction. It is intended | |
| 433 // to provide a reasonable tradeoff between performance and comprehensiveness | |
| 434 // and may be used in release code. | |
| 435 bool CheckInvariantsOnTransactionClose( | |
| 436 syncable::BaseTransaction* trans, | |
| 437 const MetahandleSet& modified_handles); | |
| 438 | |
| 439 // Forces a full check of the directory. This operation may be slow and | |
| 440 // should not be invoked outside of tests. | |
| 441 bool FullyCheckTreeInvariants(BaseTransaction *trans); | |
| 442 | |
| 443 // Purges data associated with any entries whose ModelType or ServerModelType | |
| 444 // is found in |disabled_types|, from sync directory _both_ in memory and on | |
| 445 // disk. Only valid, "real" model types are allowed in |disabled_types| (see | |
| 446 // model_type.h for definitions). | |
| 447 // 1. Data associated with |types_to_journal| is saved in the delete journal | |
| 448 // to help prevent back-from-dead problem due to offline delete in the next | |
| 449 // sync session. |types_to_journal| must be a subset of |disabled_types|. | |
| 450 // 2. Data associated with |types_to_unapply| is reset to an "unapplied" | |
| 451 // state, wherein all local data is deleted and IS_UNAPPLIED is set to true. | |
| 452 // This is useful when there's no benefit in discarding the currently | |
| 453 // downloaded state, such as when there are cryptographer errors. | |
| 454 // |types_to_unapply| must be a subset of |disabled_types|. | |
| 455 // 3. All other data is purged entirely. | |
| 456 // Note: "Purge" is just meant to distinguish from "deleting" entries, which | |
| 457 // means something different in the syncable namespace. | |
| 458 // WARNING! This can be real slow, as it iterates over all entries. | |
| 459 // WARNING! Performs synchronous I/O. | |
| 460 // Returns: true on success, false if an error was encountered. | |
| 461 virtual bool PurgeEntriesWithTypeIn(ModelTypeSet disabled_types, | |
| 462 ModelTypeSet types_to_journal, | |
| 463 ModelTypeSet types_to_unapply); | |
| 464 | |
| 465 // Resets the base_versions and server_versions of all synced entities | |
| 466 // associated with |type| to 1. | |
| 467 // WARNING! This can be slow, as it iterates over all entries for a type. | |
| 468 bool ResetVersionsForType(BaseWriteTransaction* trans, ModelType type); | |
| 469 | |
| 470 // Returns true iff the attachment identified by |attachment_id_proto| is | |
| 471 // linked to an entry. | |
| 472 // | |
| 473 // An attachment linked to a deleted entry is still considered linked if the | |
| 474 // entry hasn't yet been purged. | |
| 475 bool IsAttachmentLinked( | |
| 476 const sync_pb::AttachmentIdProto& attachment_id_proto) const; | |
| 477 | |
| 478 // Given attachment id return metahandles to all entries that reference this | |
| 479 // attachment. | |
| 480 void GetMetahandlesByAttachmentId( | |
| 481 BaseTransaction* trans, | |
| 482 const sync_pb::AttachmentIdProto& attachment_id_proto, | |
| 483 Metahandles* result); | |
| 484 | |
| 485 // Change entry to not dirty. Used in special case when we don't want to | |
| 486 // persist modified entry on disk. e.g. SyncBackupManager uses this to | |
| 487 // preserve sync preferences in DB on disk. | |
| 488 void UnmarkDirtyEntry(WriteTransaction* trans, Entry* entry); | |
| 489 | |
| 490 // Clears |ids| and fills it with the ids of attachments that need to be | |
| 491 // uploaded to the sync server. | |
| 492 void GetAttachmentIdsToUpload(BaseTransaction* trans, | |
| 493 ModelType type, | |
| 494 AttachmentIdList* ids); | |
| 495 | |
| 496 // For new entry creation only. | |
| 497 bool InsertEntry(BaseWriteTransaction* trans, EntryKernel* entry); | |
| 498 | |
| 499 // Update the attachment index for |metahandle| removing it from the index | |
| 500 // under |old_metadata| entries and add it under |new_metadata| entries. | |
| 501 void UpdateAttachmentIndex(const int64_t metahandle, | |
| 502 const sync_pb::AttachmentMetadata& old_metadata, | |
| 503 const sync_pb::AttachmentMetadata& new_metadata); | |
| 504 | |
| 505 virtual EntryKernel* GetEntryById(const Id& id); | |
| 506 virtual EntryKernel* GetEntryByClientTag(const std::string& tag); | |
| 507 EntryKernel* GetEntryByServerTag(const std::string& tag); | |
| 508 | |
| 509 virtual EntryKernel* GetEntryByHandle(int64_t handle); | |
| 510 | |
| 511 bool ReindexId(BaseWriteTransaction* trans, EntryKernel* const entry, | |
| 512 const Id& new_id); | |
| 513 | |
| 514 bool ReindexParentId(BaseWriteTransaction* trans, EntryKernel* const entry, | |
| 515 const Id& new_parent_id); | |
| 516 | |
| 517 // Accessors for the underlying Kernel. Although these are public methods, the | |
| 518 // number of classes that call these should be limited. | |
| 519 Kernel* kernel(); | |
| 520 const Kernel* kernel() const; | |
| 521 | |
| 522 private: | |
| 523 friend class SyncableDirectoryTest; | |
| 524 friend class syncer::TestUserShare; | |
| 525 FRIEND_TEST_ALL_PREFIXES(SyncableDirectoryTest, ManageDeleteJournals); | |
| 526 FRIEND_TEST_ALL_PREFIXES(SyncableDirectoryTest, | |
| 527 TakeSnapshotGetsAllDirtyHandlesTest); | |
| 528 FRIEND_TEST_ALL_PREFIXES(SyncableDirectoryTest, | |
| 529 TakeSnapshotGetsOnlyDirtyHandlesTest); | |
| 530 FRIEND_TEST_ALL_PREFIXES(SyncableDirectoryTest, | |
| 531 TakeSnapshotGetsMetahandlesToPurge); | |
| 532 FRIEND_TEST_ALL_PREFIXES(SyncableDirectoryTest, CatastrophicError); | |
| 533 | |
| 534 // You'll notice that some of the methods below are private overloads of the | |
| 535 // public ones declared above. The general pattern is that the public overload | |
| 536 // constructs a ScopedKernelLock before calling the corresponding private | |
| 537 // overload with the held ScopedKernelLock. | |
| 538 | |
| 539 virtual EntryKernel* GetEntryByHandle(const ScopedKernelLock& lock, | |
| 540 int64_t metahandle); | |
| 541 | |
| 542 virtual EntryKernel* GetEntryById(const ScopedKernelLock& lock, const Id& id); | |
| 543 | |
| 544 bool InsertEntry(const ScopedKernelLock& lock, | |
| 545 BaseWriteTransaction* trans, | |
| 546 EntryKernel* entry); | |
| 547 | |
| 548 // Remove each of |metahandle|'s attachment ids from index_by_attachment_id. | |
| 549 void RemoveFromAttachmentIndex( | |
| 550 const ScopedKernelLock& lock, | |
| 551 const int64_t metahandle, | |
| 552 const sync_pb::AttachmentMetadata& attachment_metadata); | |
| 553 | |
| 554 // Add each of |metahandle|'s attachment ids to the index_by_attachment_id. | |
| 555 void AddToAttachmentIndex( | |
| 556 const ScopedKernelLock& lock, | |
| 557 const int64_t metahandle, | |
| 558 const sync_pb::AttachmentMetadata& attachment_metadata); | |
| 559 | |
| 560 void ClearDirtyMetahandles(const ScopedKernelLock& lock); | |
| 561 | |
| 562 DirOpenResult OpenImpl( | |
| 563 const std::string& name, | |
| 564 DirectoryChangeDelegate* delegate, | |
| 565 const WeakHandle<TransactionObserver>& transaction_observer); | |
| 566 | |
| 567 // A helper that implements the logic of checking tree invariants. | |
| 568 bool CheckTreeInvariants(syncable::BaseTransaction* trans, | |
| 569 const MetahandleSet& handles); | |
| 570 | |
| 571 // Helper to prime metahandles_map, ids_map, parent_child_index, | |
| 572 // unsynced_metahandles, unapplied_update_metahandles, server_tags_map and | |
| 573 // client_tags_map from metahandles_index. The input |handles_map| will be | |
| 574 // cleared during the initialization process. | |
| 575 void InitializeIndices(MetahandlesMap* handles_map); | |
| 576 | |
| 577 // Constructs a consistent snapshot of the current Directory state and | |
| 578 // indices (by deep copy) under a ReadTransaction for use in |snapshot|. | |
| 579 // See SaveChanges() for more information. | |
| 580 void TakeSnapshotForSaveChanges(SaveChangesSnapshot* snapshot); | |
| 581 | |
| 582 // Purges from memory any unused, safe to remove entries that were | |
| 583 // successfully deleted on disk as a result of the SaveChanges that processed | |
| 584 // |snapshot|. See SaveChanges() for more information. | |
| 585 bool VacuumAfterSaveChanges(const SaveChangesSnapshot& snapshot); | |
| 586 | |
| 587 // Rolls back dirty bits in the event that the SaveChanges that | |
| 588 // processed |snapshot| failed, for example, due to no disk space. | |
| 589 void HandleSaveChangesFailure(const SaveChangesSnapshot& snapshot); | |
| 590 | |
| 591 // Used by CheckTreeInvariants. | |
| 592 void GetAllMetaHandles(BaseTransaction* trans, MetahandleSet* result); | |
| 593 | |
| 594 // Used by VacuumAfterSaveChanges. | |
| 595 bool SafeToPurgeFromMemory(WriteTransaction* trans, | |
| 596 const EntryKernel* const entry) const; | |
| 597 // A helper used by GetTotalNodeCount. | |
| 598 void GetChildSetForKernel( | |
| 599 BaseTransaction*, | |
| 600 EntryKernel* kernel_, | |
| 601 std::deque<const OrderedChildSet*>* child_sets) const; | |
| 602 | |
| 603 // Append the handles of the children of |parent_id| to |result|. | |
| 604 void AppendChildHandles(const ScopedKernelLock& lock, | |
| 605 const Id& parent_id, | |
| 606 Directory::Metahandles* result); | |
| 607 | |
| 608 // Helper methods used by PurgeDisabledTypes. | |
| 609 void UnapplyEntry(EntryKernel* entry); | |
| 610 void DeleteEntry(const ScopedKernelLock& lock, | |
| 611 bool save_to_journal, | |
| 612 EntryKernel* entry, | |
| 613 EntryKernelSet* entries_to_journal); | |
| 614 | |
| 615 // A private version of the public GetMetaHandlesOfType for when you already | |
| 616 // have a ScopedKernelLock. | |
| 617 void GetMetaHandlesOfType(const ScopedKernelLock& lock, | |
| 618 BaseTransaction* trans, | |
| 619 ModelType type, | |
| 620 std::vector<int64_t>* result); | |
| 621 | |
| 622 // Invoked by DirectoryBackingStore when a catastrophic database error is | |
| 623 // detected. | |
| 624 void OnCatastrophicError(); | |
| 625 | |
| 626 // Stops sending events to the delegate and the transaction | |
| 627 // observer. | |
| 628 void Close(); | |
| 629 | |
| 630 // Returns true if the directory had encountered an unrecoverable error. | |
| 631 // Note: Any function in |Directory| that can be called without holding a | |
| 632 // transaction need to check if the Directory already has an unrecoverable | |
| 633 // error on it. | |
| 634 bool unrecoverable_error_set(const BaseTransaction* trans) const; | |
| 635 | |
| 636 Kernel* kernel_; | |
| 637 | |
| 638 std::unique_ptr<DirectoryBackingStore> store_; | |
| 639 | |
| 640 const WeakHandle<UnrecoverableErrorHandler> unrecoverable_error_handler_; | |
| 641 base::Closure report_unrecoverable_error_function_; | |
| 642 bool unrecoverable_error_set_; | |
| 643 | |
| 644 // Not owned. | |
| 645 NigoriHandler* const nigori_handler_; | |
| 646 Cryptographer* const cryptographer_; | |
| 647 | |
| 648 InvariantCheckLevel invariant_check_level_; | |
| 649 | |
| 650 // Maintain deleted entries not in |kernel_| until it's verified that they | |
| 651 // are deleted in native models as well. | |
| 652 std::unique_ptr<DeleteJournal> delete_journal_; | |
| 653 | |
| 654 base::WeakPtrFactory<Directory> weak_ptr_factory_; | |
| 655 | |
| 656 DISALLOW_COPY_AND_ASSIGN(Directory); | |
| 657 }; | |
| 658 | |
| 659 } // namespace syncable | |
| 660 } // namespace syncer | |
| 661 | |
| 662 #endif // SYNC_SYNCABLE_DIRECTORY_H_ | |
| OLD | NEW |