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 |