# # patch "ChangeLog" # from [fa1fcddf4fb09aa568c519f5cbda8e93fa98aae7] # to [1218b5bd0ee80fb7f90b1aa1e64a29d7ae6f3c77] # # patch "pcdv.cc" # from [0bd04eacd73e9056c97f92d2a08772f5a624f147] # to [98142af12f61b816c38685f185fe3eaae0447dca] # # patch "pcdv.hh" # from [6dc79305b5e65ce553a85b79f998f0c7da205f2d] # to [f650089a46f20388d4d5976d906389af52c23934] # ======================================================================== --- ChangeLog fa1fcddf4fb09aa568c519f5cbda8e93fa98aae7 +++ ChangeLog 1218b5bd0ee80fb7f90b1aa1e64a29d7ae6f3c77 @@ -1,3 +1,8 @@ +2005-08-10 Timothy Brownawell + + * pcdv.{cc,hh} (tree merger): Teach it about file suturing. + (Needed for tracking the monotone db.) + 2005-08-03 Timothy Brownawell * pcdv.{cc,hh}: Work on merge functions for trees. ======================================================================== --- pcdv.cc 0bd04eacd73e9056c97f92d2a08772f5a624f147 +++ pcdv.cc 98142af12f61b816c38685f185fe3eaae0447dca @@ -873,6 +873,41 @@ return new_version(newleaves); } +item_status +item_status::suture(item_status const & other) const +{ + I(versions != other.versions); + I(is_dir == other.is_dir); + for (item_data::iterator o = other.versions->begin(); + o != other.versions->end(); ++o) + { + item_data::iterator m = versions->find(o->first); + if (m == versions->end()) + versions->insert(*o); + else + { + I(m->second.first == o->second.first); + std::set s; + std::vector const & ov(o->second.second); + std::vector & mv(m->second.second); + for (std::vector::const_iterator j = mv.begin(); + j != mv.end(); ++j) + s.insert(*j); + for (std::vector::const_iterator j = ov.begin(); + j != ov.end(); ++j) + { + unsigned int p = s.size(); + s.insert(*j); + if (p != s.size()) + mv.push_back(*j); + } + } + } + item_status myother(other); + myother.versions = versions; + return merge(myother); +} + std::set item_status::current_names() const { @@ -1115,7 +1150,21 @@ bool mvfile = (x->renamed_files.find(j->second) != x->renamed_files.end()); if (!deldir && !delfile && !mvdir && !mvfile) - outmap.insert(make_pair(myid, j->first)); + { + std::pair::iterator, bool> r; + r = outmap.insert(make_pair(myid, j->first)); + if (r.first->second != j->first) + { + W(F("Colliding over %1%") % j->second()); + std::map::iterator a, b; + a = out.states->find(r.first->second); + b = out.states->find(j->first); + I(a != out.states->end()); + I(b != out.states->end()); + a->second = a->second.suture(b->second); + out.states->erase(b); + } + } } } } @@ -1190,7 +1239,6 @@ || to == file_path())) W(F("undeleting %1%") % to); } - outmap.insert(make_pair(cit.intern(to()), current_id)); file_path pdir; std::vector parts; @@ -1213,6 +1261,19 @@ current_item.is_dir = is_dir; file_path recon = out.get_full_name(current_item); I(recon == to); + std::pair::iterator, bool> r; + r = outmap.insert(make_pair(cit.intern(to()), current_id)); + if (r.first->second != current_id) + { + W(F("Colliding over %1%") % to); + std::map::iterator a, b; + a = out.states->find(r.first->second); + b = out.states->find(j->first); + I(a != out.states->end()); + I(b != out.states->end()); + a->second = a->second.suture(b->second); + out.states->erase(b); + } } return out; } @@ -1357,7 +1418,9 @@ { std::set s = i->second.current_names(); I(s.size() == 1); - out.push_back(make_pair(i->first, get_full_name(*s.begin()))); + file_path fp = get_full_name(*s.begin()); + if (!(fp == file_path())) + out.push_back(make_pair(i->first, fp)); } return out; } ======================================================================== --- pcdv.hh 6dc79305b5e65ce553a85b79f998f0c7da205f2d +++ pcdv.hh f650089a46f20388d4d5976d906389af52c23934 @@ -213,6 +213,9 @@ item_status merge(item_status const & other) const; + item_status + suture(item_status const & other) const; + std::set current_names() const;