#
# add_file "parallel_iter.hh"
#
# add_file "roster_merge.cc"
#
# add_file "roster_merge.hh"
#
# patch "Makefile.am"
# from [6bec4a790685d148d6090bfa142506254913afac]
# to [4795ba7153051df7877a5ead9c548c82e286600c]
#
# patch "parallel_iter.hh"
# from []
# to [a00fa825f37d7c08c98cdc99a45d7304c4e64fd2]
#
# patch "roster.cc"
# from [a7be1586ac974d7ef805e0019a624b99160fc60c]
# to [d0c6b289a91299d1c21be24141782718a94911ae]
#
# patch "roster_merge.cc"
# from []
# to [1b0c5bb5568fee12d096cd5234721c331d90c27c]
#
# patch "roster_merge.hh"
# from []
# to [8d5fd76784742cae5f1d88354a43f30559343cff]
#
========================================================================
--- Makefile.am 6bec4a790685d148d6090bfa142506254913afac
+++ Makefile.am 4795ba7153051df7877a5ead9c548c82e286600c
@@ -45,13 +45,14 @@
globish.cc globish.hh \
string_queue.cc string_queue.hh \
paths.cc paths.hh \
+ roster_merge.cc roster_merge.hh \
\
cleanup.hh unit_tests.hh interner.hh \
cycle_detector.hh randomfile.hh adler32.hh quick_alloc.hh \
netio.hh smap.hh gettext.h \
package_revision.c package_revision.h \
package_full_revision.c package_full_revision.h options.hh \
- i18n.h hash_map.hh
+ i18n.h hash_map.hh parallel_iter.hh
NETXX_SOURCES = \
netxx/accept.cxx netxx/accept.h netxx/address.cxx \
========================================================================
--- parallel_iter.hh
+++ parallel_iter.hh a00fa825f37d7c08c98cdc99a45d7304c4e64fd2
@@ -0,0 +1,169 @@
+#ifndef __PARALLEL_ITER_HH__
+#define __PARALLEL_ITER_HH__
+
+// copyright (C) 2005 nathaniel smith
+// all rights reserved.
+// licensed to the public under the terms of the GNU GPL (>= 2)
+// see the file COPYING for details
+
+// An ugly, but handy, little helper class for doing parallel iteration
+// over maps.
+// Usage:
+// parallel::iter > i(left_map, right_map);
+// while (i.next())
+// switch (i.state())
+// {
+// case parallel::invalid:
+// I(false);
+// case parallel::in_left:
+// // use left_value(), left_key(), left_data()
+// break;
+// case parallel::in_right:
+// // use right_value(), right_key(), right_data()
+// break;
+// case parallel::in_both:
+// // use left_value(), right_value(), left_key(), right_key(),
+// // left_data(), right_data()
+// break;
+// }
+//
+// This code would make Alexander Stepanov cry; not only is it only defined
+// for maps, but it will only work on maps that use the default (std::less)
+// sort order.
+
+#include
+
+#include
+
+#include "sanity.hh"
+
+namespace parallel
+{
+ typedef enum { in_left, in_right, in_both, invalid } state_t;
+
+ template
+ class iter
+ {
+ public:
+ M const & left_map;
+ M const & right_map;
+
+ iter(M const & left_map, M const & right_map)
+ : left_map(left_map), right_map(right_map),
+ state_(invalid), started_(false), finished_(false)
+ {
+ }
+
+ bool next()
+ {
+ I(!finished_);
+ // update iterators past the last item returned
+ if (!started_)
+ {
+ left_ = left_map.begin();
+ right_ = right_map.begin();
+ started_ = true;
+ }
+ else
+ {
+ I(state_ != invalid);
+ if (state_ == in_left || state_ == in_both)
+ ++left_;
+ if (state_ == in_right || state_ == in_both)
+ ++right_;
+ }
+ // determine new state
+ I(started_);
+ if (left_ == left_map.end() && right_ == right_map.end())
+ {
+ finished_ = true;
+ state_ = invalid;
+ }
+ else if (left_ == left_map.end() && right_ != right_map.end())
+ state_ = in_right;
+ else if (left_ != left_map.end() && right_ == right_map.end())
+ state_ = in_left;
+ else
+ {
+ // Both iterators valid.
+ if (left_->first < right_->first)
+ state_ = in_left;
+ else if (right_->first < left_->first)
+ state_ = in_right;
+ else
+ {
+ I(left_->first == right_->first);
+ state_ = in_both;
+ }
+ }
+ return !finished_;
+ }
+
+ state_t state() const
+ {
+ return state_;
+ }
+
+ typename M::value_type const &
+ left_value()
+ {
+ I(state_ == in_left || state_ == in_both);
+ return *left_;
+ }
+
+ typename M::key_type const &
+ left_key()
+ {
+ return left_value().first;
+ }
+
+ typename M::value_type::second_type const &
+ left_data()
+ {
+ return left_value().second;
+ }
+
+ typename M::value_type const &
+ right_value()
+ {
+ I(state_ == in_right || state_ == in_both);
+ return *right_;
+ }
+
+ typename M::key_type const &
+ right_key()
+ {
+ return right_value().first;
+ }
+
+ typename M::value_type::second_type const &
+ right_data()
+ {
+ return right_value().second;
+ }
+
+ private:
+ state_t state_;
+ bool started_, finished_;
+ typename M::const_iterator left_;
+ typename M::const_iterator right_;
+
+ };
+
+ template void
+ dump(iter const & i, std::string & out)
+ {
+ out = boost::lexical_cast(i.state());
+ switch (i.state())
+ {
+ case in_left: out += " in_left"; break;
+ case in_right: out += " in_right"; break;
+ case in_both: out += " in_both"; break;
+ case invalid: out += " invalid"; break;
+ }
+ out += "\n";
+ }
+
+}
+
+#endif
========================================================================
--- roster.cc a7be1586ac974d7ef805e0019a624b99160fc60c
+++ roster.cc d0c6b289a91299d1c21be24141782718a94911ae
@@ -19,6 +19,7 @@
#include "revision.hh"
#include "vocab.hh"
#include "transforms.hh"
+#include "parallel_iter.hh"
#include
@@ -1527,69 +1528,6 @@
namespace
{
- // An ugly, but handy, little helper function for doing parallel iteration
- // over maps.
- // Usage:
- // std::map::const_iterator left_i, right_i;
- // parallel_state state = start;
- // while (parallel_iter_incr(state, left_map, left_i, right_map, right_i))
- // switch (state)
- // {}
-
- typedef enum { start, in_left, in_right, in_both, no_more } parallel_state;
-
- void
- dump(parallel_state const & st, std::string & out)
- {
- out = lexical_cast(st);
- switch (st)
- {
- case start: out += " start"; break;
- case in_left: out += " in_left"; break;
- case in_right: out += " in_right"; break;
- case in_both: out += " in_both"; break;
- case no_more: out += " no_more"; break;
- }
- out += "\n";
- }
- template
- bool
- parallel_iter_incr(parallel_state & state,
- M const & left, typename M::const_iterator & left_i,
- M const & right, typename M::const_iterator & right_i)
- {
- I(state != no_more);
- if (state == start)
- {
- left_i = left.begin();
- right_i = right.begin();
- }
- if (state == in_left || state == in_both)
- ++left_i;
- if (state == in_right || state == in_both)
- ++right_i;
- if (left_i == left.end() && right_i == right.end())
- state = no_more;
- else if (left_i == left.end() && right_i != right.end())
- state = in_right;
- else if (left_i != left.end() && right_i == right.end())
- state = in_left;
- else
- {
- // Both iterators valid.
- if (left_i->first < right_i->first)
- state = in_left;
- else if (right_i->first < left_i->first)
- state = in_right;
- else
- {
- I(left_i->first == right_i->first);
- state = in_both;
- }
- }
- return state != no_more;
- }
-
void delta_only_in_from(roster_t const & from,
node_id nid, node_t n,
@@ -1656,21 +1594,25 @@
// Compare attrs.
{
- full_attr_map_t::const_iterator from_ai, to_ai;
- parallel_state state = start;
- while (parallel_iter_incr(state, from_n->attrs, from_ai, to_n->attrs, to_ai))
+ parallel::iter i(from_n->attrs, to_n->attrs);
+ while (i.next())
{
- MM(state);
- if ((state == in_left || (state == in_both && !to_ai->second.first))
- && from_ai->second.first)
- safe_insert(cs.attrs_cleared,
- make_pair(to_sp, from_ai->first));
-
- else if ((state == in_right || (state == in_both && !from_ai->second.first))
- && to_ai->second.first)
- safe_insert(cs.attrs_set,
- make_pair(make_pair(to_sp, to_ai->first),
- to_ai->second.second));
+ MM(i);
+ if ((i.state() == parallel::in_left
+ || (i.state() == parallel::in_both && !i.right_data().first))
+ && i.left_data().first)
+ {
+ safe_insert(cs.attrs_cleared,
+ make_pair(to_sp, i.left_key()));
+ }
+ else if ((i.state() == parallel::in_right
+ || (i.state() == parallel::in_both && !i.left_data().first))
+ && i.right_data().first)
+ {
+ safe_insert(cs.attrs_set,
+ make_pair(make_pair(to_sp, i.right_key()),
+ i.right_data().second));
+ }
}
}
}
@@ -1680,29 +1622,25 @@
make_cset(roster_t const & from, roster_t const & to, cset & cs)
{
cs.clear();
- map::const_iterator from_i, to_i;
- parallel_state state = start;
- while (parallel_iter_incr(state,
- from.all_nodes(), from_i,
- to.all_nodes(), to_i))
+ parallel::iter