Home | History | Annotate | Download | only in engine
      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