summaryrefslogtreecommitdiffstats
path: root/chrome/browser/sync/engine/conflict_resolver.h
diff options
context:
space:
mode:
authornick@chromium.org <nick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-10 06:05:27 +0000
committernick@chromium.org <nick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-10 06:05:27 +0000
commit5852edc1b6eab234b9e048c41dd0d664ae7fc747 (patch)
tree9e5d8eb4833b76cdb11e66fc3607689e0f5e0122 /chrome/browser/sync/engine/conflict_resolver.h
parentf6059e37f8b8ac335ce18a189a13e702974a1c7e (diff)
downloadchromium_src-5852edc1b6eab234b9e048c41dd0d664ae7fc747.zip
chromium_src-5852edc1b6eab234b9e048c41dd0d664ae7fc747.tar.gz
chromium_src-5852edc1b6eab234b9e048c41dd0d664ae7fc747.tar.bz2
Initial commit of sync engine code to browser/sync.
The code is not built on any platform yet. That will arrive as a subsequent checkin. This is an implementation of the interface exposed earlier through syncapi.h. It is the client side of a sync protocol that lets users sync their browser data (currently, just bookmarks) with their Google Account. Table of contents: browser/sync/ protocol - The protocol definition, and other definitions necessary to connect to the service. syncable/ - defines a data model for syncable objects, and provides a sqlite-based backing store for this model. engine/ - includes the core sync logic, including commiting changes to the server, downloading changes from the server, resolving conflicts, other parts of the sync algorithm. engine/net - parts of the sync engine focused on the business of talking to the server. Some of this is binds a generic "server connection" interface to a concrete implementation provided by Chromium. notifier - the part of the syncer focused on the business of sending and receiving xmpp notifications. Notifications are used instead of polling to achieve very low latency change propagation. util - not necessarily sync specific utility code. Much of this is scaffolding which should either be replaced by, or merged with, the utility code in base/. BUG=none TEST=this code includes its own suite of unit tests. Review URL: http://codereview.chromium.org/194065 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@25850 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/sync/engine/conflict_resolver.h')
-rw-r--r--chrome/browser/sync/engine/conflict_resolver.h129
1 files changed, 129 insertions, 0 deletions
diff --git a/chrome/browser/sync/engine/conflict_resolver.h b/chrome/browser/sync/engine/conflict_resolver.h
new file mode 100644
index 0000000..7959106
--- /dev/null
+++ b/chrome/browser/sync/engine/conflict_resolver.h
@@ -0,0 +1,129 @@
+// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// A class that watches the syncer and attempts to resolve any conflicts that
+// occur.
+
+#ifndef CHROME_BROWSER_SYNC_ENGINE_CONFLICT_RESOLVER_H_
+#define CHROME_BROWSER_SYNC_ENGINE_CONFLICT_RESOLVER_H_
+
+#include <list>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "chrome/browser/sync/engine/conflict_resolution_view.h"
+#include "chrome/browser/sync/engine/syncer_session.h"
+#include "chrome/browser/sync/engine/syncer_status.h"
+#include "chrome/browser/sync/engine/syncer_types.h"
+#include "chrome/browser/sync/util/event_sys.h"
+#include "testing/gtest/include/gtest/gtest_prod.h" // For FRIEND_TEST
+
+namespace syncable {
+class BaseTransaction;
+class Id;
+class MutableEntry;
+class ScopedDirLookup;
+class WriteTransaction;
+} // namespace syncable
+
+namespace browser_sync {
+
+class ConflictResolver {
+ friend class SyncerTest;
+ FRIEND_TEST(SyncerTest, ConflictResolverMergeOverwritesLocalEntry);
+ public:
+ ConflictResolver();
+ ~ConflictResolver();
+ // Called by the syncer at the end of a update/commit cycle.
+ // Returns true if the syncer should try to apply its updates again.
+ bool ResolveConflicts(const syncable::ScopedDirLookup& dir,
+ ConflictResolutionView* view,
+ SyncerSession *session);
+
+ // Called by ProcessServerClientNameClash. Returns true if it's merged the
+ // items, false otherwise. Does not re-check preconditions covered in
+ // ProcessServerClientNameClash (i.e. it assumes a name clash).
+ bool AttemptItemMerge(syncable::WriteTransaction* trans,
+ syncable::MutableEntry* local_entry,
+ syncable::MutableEntry* server_entry);
+
+ private:
+ // We keep a map to record how often we've seen each conflict set. We use this
+ // to screen out false positives caused by transient server or client states,
+ // and to allow us to try to make smaller changes to fix situations before
+ // moving onto more drastic solutions.
+ typedef std::string ConflictSetCountMapKey;
+ typedef std::map<ConflictSetCountMapKey, int> ConflictSetCountMap;
+ typedef std::map<syncable::Id, int> SimpleConflictCountMap;
+
+ enum ProcessSimpleConflictResult {
+ NO_SYNC_PROGRESS, // No changes to advance syncing made.
+ SYNC_PROGRESS, // Progress made.
+ };
+
+ enum ServerClientNameClashReturn {
+ NO_CLASH,
+ SOLUTION_DEFERRED,
+ SOLVED,
+ BOGUS_SET,
+ };
+
+ // Get a key for the given set. NB: May reorder set contents.
+ // The key is currently not very efficient, but will ease debugging.
+ ConflictSetCountMapKey GetSetKey(ConflictSet* conflict_set);
+
+ void IgnoreLocalChanges(syncable::MutableEntry * entry);
+ void OverwriteServerChanges(syncable::WriteTransaction* trans,
+ syncable::MutableEntry* entry);
+
+ ProcessSimpleConflictResult ProcessSimpleConflict(
+ syncable::WriteTransaction* trans,
+ syncable::Id id,
+ SyncerSession* session);
+
+ bool ResolveSimpleConflicts(const syncable::ScopedDirLookup& dir,
+ ConflictResolutionView* view,
+ SyncerSession* session);
+
+ bool ProcessConflictSet(syncable::WriteTransaction* trans,
+ ConflictSet* conflict_set,
+ int conflict_count,
+ SyncerSession* session);
+
+ // Gives any unsynced entries in the given set new names if possible.
+ bool RenameUnsyncedEntries(syncable::WriteTransaction* trans,
+ ConflictSet* conflict_set);
+
+ ServerClientNameClashReturn ProcessServerClientNameClash(
+ syncable::WriteTransaction* trans,
+ syncable::MutableEntry* locally_named,
+ syncable::MutableEntry* server_named,
+ SyncerSession* session);
+ ServerClientNameClashReturn ProcessNameClashesInSet(
+ syncable::WriteTransaction* trans,
+ ConflictSet* conflict_set,
+ SyncerSession* session);
+
+ // Returns true if we're stuck
+ template <typename InputIt>
+ bool LogAndSignalIfConflictStuck(syncable::BaseTransaction* trans,
+ int attempt_count,
+ InputIt start, InputIt end,
+ ConflictResolutionView* view);
+
+ ConflictSetCountMap conflict_set_count_map_;
+ SimpleConflictCountMap simple_conflict_count_map_;
+
+ // Contains the ids of uncommitted items that are children of entries merged
+ // in the previous cycle. This is used to speed up the merge resolution of
+ // deep trees. Used to happen in store refresh.
+ // TODO(chron): Can we get rid of this optimization?
+ std::set<syncable::Id> children_of_merged_dirs_;
+
+ DISALLOW_COPY_AND_ASSIGN(ConflictResolver);
+};
+
+} // namespace browser_sync
+
+#endif // CHROME_BROWSER_SYNC_ENGINE_CONFLICT_RESOLVER_H_