• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2006-2009 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 // A class that watches the syncer and attempts to resolve any conflicts that
6 // occur.
7 
8 #ifndef CHROME_BROWSER_SYNC_ENGINE_CONFLICT_RESOLVER_H_
9 #define CHROME_BROWSER_SYNC_ENGINE_CONFLICT_RESOLVER_H_
10 #pragma once
11 
12 #include <set>
13 #include <string>
14 
15 #include "base/basictypes.h"
16 #include "base/gtest_prod_util.h"
17 #include "chrome/browser/sync/engine/syncer_types.h"
18 #include "chrome/common/deprecated/event_sys.h"
19 
20 namespace syncable {
21 class BaseTransaction;
22 class Id;
23 class MutableEntry;
24 class ScopedDirLookup;
25 class WriteTransaction;
26 }  // namespace syncable
27 
28 namespace browser_sync {
29 namespace sessions {
30 class StatusController;
31 }
32 
33 class ConflictResolver {
34   friend class SyncerTest;
35   FRIEND_TEST_ALL_PREFIXES(SyncerTest,
36                            ConflictResolverMergeOverwritesLocalEntry);
37  public:
38   ConflictResolver();
39   ~ConflictResolver();
40   // Called by the syncer at the end of a update/commit cycle.
41   // Returns true if the syncer should try to apply its updates again.
42   bool ResolveConflicts(const syncable::ScopedDirLookup& dir,
43                         sessions::StatusController* status);
44 
45  private:
46   // We keep a map to record how often we've seen each conflict set. We use this
47   // to screen out false positives caused by transient server or client states,
48   // and to allow us to try to make smaller changes to fix situations before
49   // moving onto more drastic solutions.
50   typedef std::string ConflictSetCountMapKey;
51   typedef std::map<ConflictSetCountMapKey, int> ConflictSetCountMap;
52   typedef std::map<syncable::Id, int> SimpleConflictCountMap;
53 
54   enum ProcessSimpleConflictResult {
55     NO_SYNC_PROGRESS,  // No changes to advance syncing made.
56     SYNC_PROGRESS,     // Progress made.
57   };
58 
59   // Get a key for the given set. NOTE: May reorder set contents. The key is
60   // currently not very efficient, but will ease debugging.
61   ConflictSetCountMapKey GetSetKey(ConflictSet* conflict_set);
62 
63   void IgnoreLocalChanges(syncable::MutableEntry* entry);
64   void OverwriteServerChanges(syncable::WriteTransaction* trans,
65                               syncable::MutableEntry* entry);
66 
67   ProcessSimpleConflictResult ProcessSimpleConflict(
68       syncable::WriteTransaction* trans,
69       const syncable::Id& id);
70 
71   bool ResolveSimpleConflicts(const syncable::ScopedDirLookup& dir,
72                               sessions::StatusController* status);
73 
74   bool ProcessConflictSet(syncable::WriteTransaction* trans,
75                           ConflictSet* conflict_set,
76                           int conflict_count);
77 
78   // Returns true if we're stuck.
79   template <typename InputIt>
80   bool LogAndSignalIfConflictStuck(syncable::BaseTransaction* trans,
81                                    int attempt_count,
82                                    InputIt start, InputIt end,
83                                    sessions::StatusController* status);
84 
85   ConflictSetCountMap conflict_set_count_map_;
86   SimpleConflictCountMap simple_conflict_count_map_;
87 
88   // Contains the ids of uncommitted items that are children of entries merged
89   // in the previous cycle. This is used to speed up the merge resolution of
90   // deep trees. Used to happen in store refresh.
91   // TODO(chron): Can we get rid of this optimization?
92   std::set<syncable::Id> children_of_merged_dirs_;
93 
94   DISALLOW_COPY_AND_ASSIGN(ConflictResolver);
95 };
96 
97 }  // namespace browser_sync
98 
99 #endif  // CHROME_BROWSER_SYNC_ENGINE_CONFLICT_RESOLVER_H_
100