# # # patch "database.cc" # from [2e1c65cb247666cfbf9d870f2a8be91153956625] # to [2dfd49dd717b8644a1667630682e1fdccd64261f] # # patch "database.hh" # from [b78ece31bb4d90bc92abd7d29b46ef9651ae7975] # to [2578bdeca4a0fbda800608a4111a37f10d41cc45] # # patch "roster_delta.cc" # from [5225677470dde8755581d7ae22081845ac428e60] # to [14db37168a524e90dd917df322bc4e5d3997a714] # # patch "roster_delta.hh" # from [8a78d49fa1d7b16ef457cf04367e97d052d1afcb] # to [c6d48aafb77769d2ebc667cc5720cf05c9907695] # # patch "unit-tests/roster.cc" # from [98207c6ccf55333e5407e3c32be85876426e34d6] # to [6cbb6cf4d39817750a5b82c939a2be9a23c1d58d] # ============================================================ --- database.cc 2e1c65cb247666cfbf9d870f2a8be91153956625 +++ database.cc 2dfd49dd717b8644a1667630682e1fdccd64261f @@ -2940,7 +2940,7 @@ database::put_roster_for_revision(revisi // const'ify the objects, suitable for caching etc. roster_t_cp ros = ros_writeable; marking_map_cp mm = mm_writeable; - put_roster(new_id, ros, mm); + put_roster(new_id, rev, ros, mm); } bool @@ -4314,6 +4314,7 @@ database::put_roster(revision_id const & void database::put_roster(revision_id const & rev_id, + revision_t const & rev, roster_t_cp const & roster, marking_map_cp const & marking) { @@ -4328,22 +4329,24 @@ database::put_roster(revision_id const & imp->roster_cache.insert_dirty(rev_id, make_pair(roster, marking)); - set parents; - get_revision_parents(rev_id, parents); - // Now do what deltify would do if we bothered - for (set::const_iterator i = parents.begin(); - i != parents.end(); ++i) + size_t num_edges = rev.edges.size(); + for (edge_map::const_iterator i = rev.edges.begin(); + i != rev.edges.end(); ++i) { - if (null_id(*i)) + revision_id old_rev = edge_old_revision(*i); + if (null_id(old_rev)) continue; - revision_id old_rev = *i; if (imp->roster_base_stored(old_rev)) { cached_roster cr; get_roster_version(old_rev, cr); roster_delta reverse_delta; - delta_rosters(*roster, *marking, *(cr.first), *(cr.second), reverse_delta); + cset const & changes = edge_changes(i); + delta_rosters(*roster, *marking, + *(cr.first), *(cr.second), + reverse_delta, + num_edges > 1 ? 0 : &changes); if (imp->roster_cache.exists(old_rev)) imp->roster_cache.mark_clean(old_rev); imp->drop(old_rev.inner(), "rosters"); ============================================================ --- database.hh b78ece31bb4d90bc92abd7d29b46ef9651ae7975 +++ database.hh 2578bdeca4a0fbda800608a4111a37f10d41cc45 @@ -230,6 +230,7 @@ private: cached_roster & cr); void put_roster(revision_id const & rev_id, + revision_t const & rev, roster_t_cp const & roster, marking_map_cp const & marking); ============================================================ --- roster_delta.cc 5225677470dde8755581d7ae22081845ac428e60 +++ roster_delta.cc 14db37168a524e90dd917df322bc4e5d3997a714 @@ -18,6 +18,7 @@ #include "safe_map.hh" #include "parallel_iter.hh" +#include "cset.hh" #include "roster.hh" #include "roster_delta.hh" #include "basic_io.hh" @@ -123,7 +124,7 @@ namespace } void - do_delta_for_node_only_in_dest(node_t new_n, roster_delta_t & d) + do_delta_for_node_only_in_dest(const_node_t new_n, roster_delta_t & d) { node_id nid = new_n->self; pair new_loc(new_n->parent, new_n->name); @@ -145,7 +146,7 @@ namespace } void - do_delta_for_node_in_both(node_t old_n, node_t new_n, roster_delta_t & d) + do_delta_for_node_in_both(const_node_t old_n, const_node_t new_n, roster_delta_t & d) { I(old_n->self == new_n->self); node_id nid = old_n->self; @@ -193,9 +194,11 @@ namespace } void - make_roster_delta_t(roster_t const & from, marking_map const & from_markings, - roster_t const & to, marking_map const & to_markings, - roster_delta_t & d) + make_unconstrained_roster_delta_t(roster_t const & from, + marking_map const & from_markings, + roster_t const & to, + marking_map const & to_markings, + roster_delta_t & d) { MM(from); MM(from_markings); @@ -258,6 +261,122 @@ namespace } } + void + make_roster_delta_t(roster_t const & from, marking_map const & from_markings, + roster_t const & to, marking_map const & to_markings, + roster_delta_t & d, cset const * reverse_csp) + { + if (!reverse_csp) + { + make_unconstrained_roster_delta_t(from, from_markings, + to, to_markings, + d); + } + else + { + cset const & cs(*reverse_csp); + MM(cs); + + typedef std::set::const_iterator path_iter; + typedef std::map::const_iterator path_id_iter; + typedef std::map::const_iterator path_path_iter; + typedef std::map >::const_iterator del_iter; + typedef std::set >::const_iterator attr_rm_iter; + typedef std::map, attr_value>::const_iterator attr_del_iter; + + // in to, or cset source + for (path_iter i = cs.nodes_deleted.begin(); + i != cs.nodes_deleted.end(); ++i) + { + const_node_t n = to.get_node(*i); + do_delta_for_node_only_in_dest(n, d); + marking_map::const_iterator m = to_markings.find(n->self); + I(m != to_markings.end()); + safe_insert(d.markings_changed, *m); + } + + + class tracking_doer + { + roster_t const & lr; + roster_t const & rr; + marking_map const & lmm; + marking_map const & rmm; + roster_delta_t & d; + std::set _done; + public: + tracking_doer(roster_t const & l, roster_t const & r, + marking_map const & lmm, + marking_map const & rmm, + roster_delta_t & d) + : lr(l), rr(r), lmm(lmm), rmm(rmm), d(d) + { } + void note(file_path const & p) + { + _done.insert(p); + } + bool try_do(file_path const & lp) + { + pair x = _done.insert(lp); + if (!x.second) + return false; + + const_node_t l = lr.get_node(lp); + const_node_t r = rr.get_node(l->self); + do_delta_for_node_in_both(l, r, d); + + marking_map::const_iterator lm = lmm.find(l->self); + I(lm != lmm.end()); + + marking_map::const_iterator rm = rmm.find(r->self); + I(rm != rmm.end()); + + if (!(lm == rm)) + safe_insert(d.markings_changed, *rm); + + return true; + } + }; + tracking_doer doer(from, to, from_markings, to_markings, d); + + // in from, or cset target + for (path_iter i = cs.dirs_added.begin(); + i != cs.dirs_added.end(); ++i) + { + doer.note(*i); + safe_insert(d.nodes_deleted, from.get_node(*i)->self); + } + for (path_id_iter i = cs.files_added.begin(); + i != cs.files_added.end(); ++i) + { + doer.note(i->first); + safe_insert(d.nodes_deleted, from.get_node(i->first)->self); + } + + // in both + for (path_path_iter i = cs.nodes_renamed.begin(); + i != cs.nodes_renamed.end(); ++i) + { + doer.try_do(i->second); + } + for (del_iter i = cs.deltas_applied.begin(); + i != cs.deltas_applied.end(); ++i) + { + doer.try_do(i->first); + } + for (attr_rm_iter i = cs.attrs_cleared.begin(); + i != cs.attrs_cleared.end(); ++i) + { + doer.try_do(i->first); + } + for (attr_del_iter i = cs.attrs_set.begin(); + i != cs.attrs_set.end(); ++i) + { + doer.try_do(i->first.first); + } + } + } + namespace syms { symbol const deleted("deleted"); @@ -486,14 +605,15 @@ delta_rosters(roster_t const & from, mar void delta_rosters(roster_t const & from, marking_map const & from_markings, roster_t const & to, marking_map const & to_markings, - roster_delta & del) + roster_delta & del, + cset const * reverse_cs) { MM(from); MM(from_markings); MM(to); MM(to_markings); roster_delta_t d; - make_roster_delta_t(from, from_markings, to, to_markings, d); + make_roster_delta_t(from, from_markings, to, to_markings, d, reverse_cs); data dat; print_roster_delta_t(dat, d); del = roster_delta(dat(), origin::internal); ============================================================ --- roster_delta.hh 8a78d49fa1d7b16ef457cf04367e97d052d1afcb +++ roster_delta.hh c6d48aafb77769d2ebc667cc5720cf05c9907695 @@ -15,10 +15,15 @@ #include "rev_types.hh" +// You should pass a null for 'reverse_cs' if this is a merge edge, because in +// that case even untouched nodes can have different mark sets. +// Note that 'reverse_cs' is the cset that starts with 'to' and gives 'from', +// because that's what's available in the only place this is used. void delta_rosters(roster_t const & from, marking_map const & from_markings, roster_t const & to, marking_map const & to_markings, - roster_delta & del); + roster_delta & del, + cset const * reverse_cs); // mutates its arguments void ============================================================ --- unit-tests/roster.cc 98207c6ccf55333e5407e3c32be85876426e34d6 +++ unit-tests/roster.cc 6cbb6cf4d39817750a5b82c939a2be9a23c1d58d @@ -151,7 +151,7 @@ spin(roster_t const & from, marking_map MM(to_marking); roster_delta del; MM(del); - delta_rosters(from, from_marking, to, to_marking, del); + delta_rosters(from, from_marking, to, to_marking, del, 0); roster_t tmp(from); MM(tmp); @@ -162,7 +162,7 @@ spin(roster_t const & from, marking_map I(tmp_marking == to_marking); roster_delta del2; - delta_rosters(from, from_marking, tmp, tmp_marking, del2); + delta_rosters(from, from_marking, tmp, tmp_marking, del2, 0); I(del == del2); }