# # # patch "basic_io.hh" # from [9ad16beabaf2b1c272a356e8cf41bba97f7e1562] # to [4e4f6fbd7d99c02f9c7e9e8b117a3e29dffe02d4] # # patch "roster.cc" # from [26d0595c777d04a5fee1da95c1fcef793fdcd578] # to [3b0b76585f1203703b5c52b77c12e7ece013fdc6] # # patch "roster.hh" # from [3d64ba3885d4d9daa5534125d0b58ed00307fb11] # to [cfedbe0ed469e668c8993de34b78b8641c942b95] # # patch "roster_merge.cc" # from [5cbf793f50cf62a073ce837d337569d4ddb9475b] # to [487decdf5c0b30fdc79b6b9f3c9fb0c2c1347a06] # ============================================================ --- basic_io.hh 9ad16beabaf2b1c272a356e8cf41bba97f7e1562 +++ basic_io.hh 4e4f6fbd7d99c02f9c7e9e8b117a3e29dffe02d4 @@ -46,6 +46,7 @@ namespace basic_io symbol const dormant_attr("dormant_attr"); symbol const path_mark("path_mark"); + symbol const existence_mark("existence_mark"); symbol const content_mark("content_mark"); symbol const attr_mark("attr_mark"); } ============================================================ --- roster.cc 26d0595c777d04a5fee1da95c1fcef793fdcd578 +++ roster.cc 3b0b76585f1203703b5c52b77c12e7ece013fdc6 @@ -82,6 +82,8 @@ dump(marking_t const & marking, string & oss << "parent_name: " << tmp << '\n'; dump(marking.file_content, tmp); oss << "file_content: " << tmp << '\n'; + dump(marking.existence, tmp); + oss << "existence: " << tmp << '\n'; oss << "attrs (number: " << marking.attrs.size() << "):\n"; for (map >::const_iterator i = marking.attrs.begin(); i != marking.attrs.end(); ++i) @@ -1061,6 +1063,7 @@ roster_t::check_sane_against(marking_map { I(!null_id(mi->second.birth_revision)); I(!mi->second.parent_name.empty()); + I(!mi->second.existence.empty()); if (is_file_t(ri->second)) I(!mi->second.file_content.empty()); @@ -1467,6 +1470,7 @@ namespace mark_new_node(revision_id const & new_rid, node_t n, marking_t & new_marking) { new_marking.birth_revision = new_rid; + new_marking.existence.insert(new_rid); I(new_marking.parent_name.empty()); new_marking.parent_name.insert(new_rid); I(new_marking.file_content.empty()); @@ -1481,8 +1485,8 @@ namespace } void - mark_unmerged_node(marking_t const & parent_marking, node_t parent_n, - revision_id const & new_rid, node_t n, + mark_unmerged_node(marking_t const & parent_marking, bool parent_existence, node_t parent_n, + revision_id const & new_rid, node_t n, bool & n_existence, marking_t & new_marking) { // SPEEDUP?: the common case here is that the parent and child nodes are @@ -1501,6 +1505,12 @@ namespace make_pair(n->parent, n->name), new_marking.parent_name); + mark_unmerged_scalar(parent_marking.existence, + parent_existence, + new_rid, + n_existence, + new_marking.existence); + if (is_file_t(n)) mark_unmerged_scalar(parent_marking.file_content, downcast_to_file_t(parent_n)->content, @@ -1525,13 +1535,16 @@ namespace void mark_merged_node(marking_t const & left_marking, + bool left_existence, set const & left_uncommon_ancestors, node_t ln, marking_t const & right_marking, + bool right_existence, set const & right_uncommon_ancestors, node_t rn, revision_id const & new_rid, node_t n, + bool & n_existence, marking_t & new_marking) { I(same_type(ln, n) && same_type(rn, n)); @@ -1546,6 +1559,14 @@ namespace new_rid, make_pair(n->parent, n->name), new_marking.parent_name); + // existence + mark_merged_scalar(left_marking.existence, left_uncommon_ancestors, + left_existence, + right_marking.existence, right_uncommon_ancestors, + right_existence, + new_rid, + n_existence, + new_marking.existence); // content if (is_file_t(n)) { @@ -1639,6 +1660,7 @@ mark_merge_roster(roster_t const & left_ bool exists_in_right = (rni != right_roster.all_nodes().end()); marking_t new_marking; + bool new_existence; if (!exists_in_left && !exists_in_right) mark_new_node(new_rid, n, new_marking); @@ -1650,8 +1672,8 @@ mark_merge_roster(roster_t const & left_ // must be unborn on the left (as opposed to dead) I(right_uncommon_ancestors.find(right_marking.birth_revision) != right_uncommon_ancestors.end()); - mark_unmerged_node(right_marking, right_node, - new_rid, n, new_marking); + mark_unmerged_node(right_marking, exists_in_right, right_node, + new_rid, n, new_existence, new_marking); } else if (exists_in_left && !exists_in_right) { @@ -1660,20 +1682,22 @@ mark_merge_roster(roster_t const & left_ // must be unborn on the right (as opposed to dead) I(left_uncommon_ancestors.find(left_marking.birth_revision) != left_uncommon_ancestors.end()); - mark_unmerged_node(left_marking, left_node, - new_rid, n, new_marking); + mark_unmerged_node(left_marking, exists_in_left, left_node, + new_rid, n, new_existence, new_marking); } else { node_t const & left_node = lni->second; node_t const & right_node = rni->second; - mark_merged_node(safe_get(left_markings, n->self), + mark_merged_node(safe_get(left_markings, n->self), exists_in_left, left_uncommon_ancestors, left_node, - safe_get(right_markings, n->self), + safe_get(right_markings, n->self), exists_in_right, right_uncommon_ancestors, right_node, - new_rid, n, new_marking); + new_rid, n, new_existence, new_marking); } + I(new_existence); + safe_insert(new_markings, make_pair(i->first, new_marking)); } } @@ -1956,12 +1980,14 @@ mark_roster_with_one_parent(roster_t con i != child.all_nodes().end(); ++i) { marking_t new_marking; + bool n_existence = true; if (parent.has_node(i->first)) - mark_unmerged_node(safe_get(parent_markings, i->first), + mark_unmerged_node(safe_get(parent_markings, i->first), true, parent.get_node(i->first), - child_rid, i->second, new_marking); + child_rid, i->second, n_existence, new_marking); else mark_new_node(child_rid, i->second, new_marking); + I(n_existence); safe_insert(child_markings, make_pair(i->first, new_marking)); } @@ -2449,6 +2475,10 @@ push_marking(basic_io::stanza & st, i != mark.parent_name.end(); ++i) st.push_hex_pair(basic_io::syms::path_mark, i->inner()); + for (set::const_iterator i = mark.existence.begin(); + i != mark.existence.end(); ++i) + st.push_hex_pair(basic_io::syms::existence_mark, i->inner()); + if (is_file) { for (set::const_iterator i = mark.file_content.begin(); @@ -2487,6 +2517,12 @@ parse_marking(basic_io::parser & pa, pa.hex(rev); safe_insert(marking.parent_name, revision_id(rev)); } + else if (pa.symp(basic_io::syms::existence_mark)) + { + pa.sym(); + pa.hex(rev); + safe_insert(marking.existence, revision_id(rev)); + } else if (pa.symp(basic_io::syms::content_mark)) { pa.sym(); ============================================================ --- roster.hh 3d64ba3885d4d9daa5534125d0b58ed00307fb11 +++ roster.hh cfedbe0ed469e668c8993de34b78b8641c942b95 @@ -153,6 +153,7 @@ struct marking_t revision_id birth_revision; std::set parent_name; std::set file_content; + std::set existence; std::map > attrs; marking_t() {}; bool operator==(marking_t const & other) const @@ -160,6 +161,7 @@ struct marking_t return birth_revision == other.birth_revision && parent_name == other.parent_name && file_content == other.file_content + && existence == other.existence && attrs == other.attrs; } }; ============================================================ --- roster_merge.cc 5cbf793f50cf62a073ce837d337569d4ddb9475b +++ roster_merge.cc 487decdf5c0b30fdc79b6b9f3c9fb0c2c1347a06 @@ -400,6 +400,7 @@ roster_merge(roster_t const & left_paren // First handle lifecycles, by die-die-die merge -- our result will contain // everything that is alive in both parents, or alive in one and unborn in // the other, exactly. + { parallel::iter i(left_parent.all_nodes(), right_parent.all_nodes()); while (i.next())