#
#
# add_file "gsync.hh"
# content [ce72087f6b1b5d34b400b548808596c346f9b594]
#
# patch "Makefile.am"
# from [2175237275af02c1314fecd0fcb42888387bd127]
# to [9ce86ec149986e741fd3ed00ed79db4010db59b7]
#
# patch "cmd_netsync.cc"
# from [d1b9aead3c0742a08d4c5035e14ede9743c50831]
# to [991ceecf7fa6728da543449fa1162b83da951058]
#
# patch "gsync.cc"
# from [8c41e5fb9705fcef796832316271582acd76c2df]
# to [5f8a87f1a21027f3661fbd8b6fbcc9614ef0c201]
#
# patch "http_client.cc"
# from [ebd2d796bfaf1f4e027ad3ff6d2d43c3ac2cc93c]
# to [4bd52563930130759bd40ff3d841d00013500d20]
#
# patch "http_client.hh"
# from [454f6074e7408d53b97bca7078c6f7f4c07c2b93]
# to [8eac2ba77c84328372e3f2980bac2c91f70a5304]
#
# patch "netsync.cc"
# from [0c2c0074d6b643fe3dd742b0b2bbc5f9b0341008]
# to [b5089c12a9b77cdf03d89984fafaf81d783bda9d]
#
============================================================
--- gsync.hh ce72087f6b1b5d34b400b548808596c346f9b594
+++ gsync.hh ce72087f6b1b5d34b400b548808596c346f9b594
@@ -0,0 +1,48 @@
+#ifndef __GSYNC_HH__
+#define __GSYNC_HH__
+
+// Copyright (C) 2008 Markus Schiltknecht
+//
+// This program is made available under the GNU GPL version 2.0 or
+// greater. See the accompanying file COPYING for details.
+//
+// This program is distributed WITHOUT ANY WARRANTY; without even the
+// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+// PURPOSE.
+
+#include "base.hh"
+
+#include
+
+#include "vocab.hh"
+
+struct uri;
+struct globish;
+class lua_hooks;
+class database;
+
+class
+channel
+{
+public:
+ virtual
+ void inquire_about_revs(std::set const & query_set,
+ std::set & theirs) const = 0;
+ virtual
+ void push_rev(revision_id const & rid) const = 0;
+};
+
+extern void
+run_gsync_protocol(lua_hooks & lua, database & db, channel const & ch,
+ globish const & include_pattern,
+ globish const & exclude_pattern);
+
+// Local Variables:
+// mode: C++
+// fill-column: 76
+// c-file-style: "gnu"
+// indent-tabs-mode: nil
+// End:
+// vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s:
+
+#endif // __GSYNC_HH__
============================================================
--- Makefile.am 2175237275af02c1314fecd0fcb42888387bd127
+++ Makefile.am 9ce86ec149986e741fd3ed00ed79db4010db59b7
@@ -47,7 +47,7 @@ MOST_SOURCES = \
enumerator.cc enumerator.hh \
net_common.cc net_common.hh \
netsync.cc \
- gsync.cc \
+ gsync.cc gsync.hh \
netxx_pipe.cc netxx_pipe.hh \
netcmd.cc netcmd.hh \
merkle_tree.cc merkle_tree.hh \
@@ -317,7 +317,7 @@ UNIT_TEST_SRC_SUPPORT = \
# these files do not contain unit tests, but are required for unit testing
# and must be recompiled for that purpose
UNIT_TEST_SRC_SUPPORT = \
- roster_delta.cc json_msgs.cc http_client.cc net_common.cc
+ roster_delta.cc
# these files do not contain unit tests; they are required for unit
# testing, but can be used "as is" from the main build. (many of
============================================================
--- cmd_netsync.cc d1b9aead3c0742a08d4c5035e14ede9743c50831
+++ cmd_netsync.cc 991ceecf7fa6728da543449fa1162b83da951058
@@ -1,9 +1,11 @@
#include "base.hh"
#include "cmd.hh"
#include "diff_patch.hh"
#include "netcmd.hh"
#include "globish.hh"
+#include "gsync.hh"
+#include "http_client.hh"
#include "keys.hh"
#include "key_store.hh"
#include "cert.hh"
@@ -491,11 +493,6 @@ CMD_NO_WORKSPACE(serve, "serve", "", CMD
globish("*"), globish(""));
}
-void
-run_gsync_protocol(options & opts, lua_hooks & lua, database & db, utf8 const & addr,
- globish const & include_pattern,
- globish const & exclude_pattern);
-
CMD(gsync, "gsync", "", CMD_REF(network),
N_("[ADDRESS[:PORTNUMBER] [PATTERN ...]]"),
N_("Synchronizes branches with a netsync server"),
@@ -514,7 +511,11 @@ CMD(gsync, "gsync", "", CMD_REF(network)
extract_patterns(app.opts, db, args, include_pattern, exclude_pattern);
find_key_if_needed(app.opts, app.lua, db, keys, addr, include_pattern, exclude_pattern);
- run_gsync_protocol(app.opts, app.lua, db, addr, include_pattern, exclude_pattern);
+ uri u;
+ parse_uri(addr(), u);
+ http_client h(app.opts, app.lua, u, include_pattern, exclude_pattern);
+ run_gsync_protocol(app.lua, db, http_channel(h),
+ include_pattern, exclude_pattern);
}
============================================================
--- gsync.cc 8c41e5fb9705fcef796832316271582acd76c2df
+++ gsync.cc 5f8a87f1a21027f3661fbd8b6fbcc9614ef0c201
@@ -14,14 +14,13 @@
#include
#include
+#include "constants.hh"
#include "database.hh"
#include "globish.hh"
-#include "http_client.hh"
-#include "json_io.hh"
-#include "json_msgs.hh"
+#include "graph.hh"
+#include "gsync.hh"
#include "revision.hh"
#include "sanity.hh"
-#include "lexical_cast.hh"
#include "uri.hh"
//
@@ -81,9 +80,6 @@ using std::pair;
using std::string;
using std::pair;
-using json_io::json_value_t;
-using boost::lexical_cast;
-
/////////////////////////////////////////////////////////////////////
// core logic of gsync algorithm
/////////////////////////////////////////////////////////////////////
@@ -107,20 +103,8 @@ do_set_difference(set const
}
-static void
-inquire_about_revs(http_client & h,
- set const & query_set,
- set & theirs)
-{
- theirs.clear();
- json_value_t query = encode_msg_inquire(query_set);
- json_value_t response = h.transact_json(query);
- E(decode_msg_confirm(response, theirs),
- F("received unexpected reply to 'inquire' message"));
-}
-
static void
-determine_common_core(http_client & h,
+determine_common_core(channel const & ch,
set const & our_revs,
rev_ancestry_map const & child_to_parent_map,
rev_ancestry_map const & parent_to_child_map,
@@ -149,7 +133,7 @@ determine_common_core(http_client & h,
set revs_present, present_ancs, present_closure;
set revs_absent, absent_descs, absent_closure;
- inquire_about_revs(h, query_revs, revs_present);
+ ch.inquire_about_revs(query_revs, revs_present);
do_set_difference(query_revs, revs_present, revs_absent);
L(FL("pass #%d: inquired about %d revs, they have %d of them, missing %d of them")
@@ -196,7 +180,7 @@ do_missing_playback(database & db,
static void
do_missing_playback(database & db,
- http_client & h,
+ channel const & ch,
set & core_frontier,
set & revs_to_push,
rev_ancestry_map const & parent_to_child_map)
@@ -237,6 +221,8 @@ do_missing_playback(database & db,
L(FL(" pushing revision %s (child of rev %s)")
% i->second % i->first);
+ ch.push_rev(i->second);
+
revs_to_push.erase(i->second);
core_frontier.erase(i->first);
core_frontier.insert(i->second);
@@ -250,22 +236,17 @@ request_missing_playback(database & db,
static void
request_missing_playback(database & db,
- http_client & h,
+ channel const & ch,
set const & core_frontier)
{
}
void
-run_gsync_protocol(options & opts, lua_hooks & lua, database & db,
- utf8 const & addr,
+run_gsync_protocol(lua_hooks & lua, database & db, channel const & ch,
globish const & include_pattern,
globish const & exclude_pattern)
{
- uri u;
- parse_uri(addr(), u);
- http_client h(opts, lua, u, include_pattern, exclude_pattern);
-
bool pushing = true, pulling = true;
rev_ancestry_map parent_to_child_map, child_to_parent_map;
@@ -283,7 +264,7 @@ run_gsync_protocol(options & opts, lua_h
}
set common_core;
- determine_common_core(h, our_revs, child_to_parent_map, parent_to_child_map, common_core);
+ determine_common_core(ch, our_revs, child_to_parent_map, parent_to_child_map, common_core);
set ours_alone;
do_set_difference(our_revs, common_core, ours_alone);
@@ -293,18 +274,88 @@ run_gsync_protocol(options & opts, lua_h
erase_ancestors(db, core_frontier);
if (pushing)
- do_missing_playback(db, h, core_frontier, ours_alone,
+ do_missing_playback(db, ch, core_frontier, ours_alone,
parent_to_child_map);
if (pulling)
- request_missing_playback(db, h, core_frontier);
+ request_missing_playback(db, ch, core_frontier);
}
#ifdef BUILD_UNIT_TESTS
#include "unit_tests.hh"
-UNIT_TEST(gsync, gsync)
+class test_channel
+ : public channel
{
+ set & theirs;
+public:
+ test_channel(set & theirs)
+ : theirs(theirs)
+ { };
+
+ void inquire_about_revs(set const & query_set,
+ set & result) const
+ {
+ result.clear();
+ for (set::const_iterator i = query_set.begin();
+ i != query_set.end(); ++i)
+ if (theirs.find(*i) != theirs.end())
+ result.insert(*i);
+ };
+
+ void push_rev(revision_id const & rid) const
+ {
+ I(false);
+ }
+};
+
+UNIT_TEST(gsync, gsync_common_core)
+{
+ L(FL("TEST: begin checking gsync protocol functions"));
+
+ revision_id rid1("0000000000000000000000000000000000000001");
+ revision_id rid2("0000000000000000000000000000000000000002");
+ revision_id rid3("0000000000000000000000000000000000000003");
+ revision_id rid4("0000000000000000000000000000000000000004");
+ revision_id rid5("0000000000000000000000000000000000000005");
+ revision_id rid6("0000000000000000000000000000000000000006");
+ revision_id rid7("0000000000000000000000000000000000000007");
+ revision_id rid8("0000000000000000000000000000000000000008");
+
+ // simulate having revisions 1, 2, 3, 5, 6 and 8 locally
+ set ours;
+ ours.insert(rid1);
+ ours.insert(rid2);
+ ours.insert(rid3);
+ ours.insert(rid5);
+ ours.insert(rid6);
+ ours.insert(rid8);
+
+ // prepaire an ancestry map
+ rev_ancestry_map parent_to_child_map, child_to_parent_map;
+ parent_to_child_map.insert(make_pair(rid1, rid2));
+ parent_to_child_map.insert(make_pair(rid1, rid3));
+ parent_to_child_map.insert(make_pair(rid2, rid5));
+ parent_to_child_map.insert(make_pair(rid3, rid5));
+ parent_to_child_map.insert(make_pair(rid5, rid6));
+ parent_to_child_map.insert(make_pair(rid5, rid8));
+ invert_ancestry(parent_to_child_map, child_to_parent_map);
+
+ // the other side has revisions 1, 2, 4 and 7
+ set theirs;
+ theirs.insert(rid1);
+ theirs.insert(rid2);
+ theirs.insert(rid4);
+ theirs.insert(rid7);
+
+ // setup the test channel and determine the common core
+ test_channel ch(theirs);
+ set common_core;
+ determine_common_core(ch, ours, child_to_parent_map, parent_to_child_map, common_core);
+
+ I(common_core.size() == 2);
+ I(common_core.find(rid1) != common_core.end());
+ I(common_core.find(rid2) != common_core.end());
}
#endif
============================================================
--- http_client.cc ebd2d796bfaf1f4e027ad3ff6d2d43c3ac2cc93c
+++ http_client.cc 4bd52563930130759bd40ff3d841d00013500d20
@@ -13,6 +13,7 @@
#include "globish.hh"
#include "http_client.hh"
#include "json_io.hh"
+#include "json_msgs.hh"
#include "net_common.hh"
#include "sanity.hh"
#include "lexical_cast.hh"
@@ -26,6 +27,7 @@
#include "netxx_pipe.hh"
#include
+#include
#include
#include
@@ -34,10 +36,10 @@ using std::vector;
using boost::shared_ptr;
using boost::lexical_cast;
using std::vector;
+using std::set;
using std::string;
using std::iostream;
-
using Netxx::Netbuf;
using Netxx::Timeout;
using Netxx::StreamBase;
@@ -191,6 +193,23 @@ http_client::parse_http_response(std::st
}
+
+/////////////////////////////////////////////////////////////////////
+// http_channel adaptor
+/////////////////////////////////////////////////////////////////////
+
+void
+http_channel::inquire_about_revs(set const & query_set,
+ set & theirs) const
+{
+ theirs.clear();
+ json_value_t query = encode_msg_inquire(query_set);
+ json_value_t response = client.transact_json(query);
+ E(decode_msg_confirm(response, theirs),
+ F("received unexpected reply to 'inquire' message"));
+}
+
+
// Local Variables:
// mode: C++
// fill-column: 76
============================================================
--- http_client.hh 454f6074e7408d53b97bca7078c6f7f4c07c2b93
+++ http_client.hh 8eac2ba77c84328372e3f2980bac2c91f70a5304
@@ -15,6 +15,7 @@
#include "base.hh"
#include "constants.hh"
+#include "gsync.hh"
#include "json_io.hh"
#include
@@ -53,6 +54,19 @@ http_client
void crlf();
};
+class http_channel
+ : public channel
+{
+ http_client & client;
+public:
+ http_channel(http_client & c)
+ : client(c)
+ { };
+ virtual void inquire_about_revs(std::set const & query_set,
+ std::set & theirs) const;
+ virtual void push_rev(revision_id const & rid) const;
+};
+
// Local Variables:
// mode: C++
// fill-column: 76
============================================================
--- netsync.cc 0c2c0074d6b643fe3dd742b0b2bbc5f9b0341008
+++ netsync.cc b5089c12a9b77cdf03d89984fafaf81d783bda9d
@@ -27,6 +27,7 @@
#include "cert.hh"
#include "constants.hh"
#include "enumerator.hh"
+#include "gsync.hh"
#include "keys.hh"
#include "lua.hh"
#include "merkle_tree.hh"