# # patch "ChangeLog" # from [d17897188e1466631529c539c0a8ea8288eae1e5] # to [45d52de4c1d3b02795d3e177dc46a7868469cbb1] # # patch "commands.cc" # from [1f63172b2efdc7f3b14c034b5a0a101c3433c6c8] # to [619c97f154a148333f4d045bfab003359c533810] # # patch "contrib/monoprof.sh" # from [1bb2ed75727369fc101d6852b914f8346edaaa5a] # to [920671704fc04418a746009cffaa8a1452a6bf85] # # patch "pcdv.cc" # from [1a89fcfc9932fe819917b1f5d09cf5e097fe4900] # to [8f5d9105a82f69c6aea06bd547679403f979846f] # # patch "pcdv.hh" # from [99cd22bde02f3a20af2fd2afc574a02248bf3884] # to [e53433a7651985f8a0aeff23660f7d21f40eb813] # --- ChangeLog +++ ChangeLog @@ -1,3 +1,10 @@ +2005-06-29 Timothy Brownawell + + * pcdv.{cc,hh}: many changes, including adding test code. + Does not work properly on test code. + * commands.cc: pcdv runs new test code first + * contrib/monoprof.sh: pcdv test uses different file now + 2005-06-27 Timothy Brownawell * new files: pcdv.{cc,hh} --- commands.cc +++ commands.cc @@ -3822,6 +3822,9 @@ "precise-cdv merge FILENAME in the two given revisions", OPT_NONE) { + if (!pcdv_test()) + return; + if (args.size() != 3) throw usage(name); @@ -3849,9 +3852,9 @@ map files; file_state empty = file_state(vector(), string()); std::set heads; + file_state p(empty); while (!roots.empty()) { - file_state p(empty); vector const & ps(parents[roots.front()].second); if (ps.size() == 0) p = empty; @@ -3923,8 +3926,8 @@ for (vector::iterator j = i->left.begin(); j != i->left.end(); ++j) cout<<" "<<*j; + lastok = true; } - lastok = true; } } } --- contrib/monoprof.sh +++ contrib/monoprof.sh @@ -382,8 +382,8 @@ pushd ${BUILDDIR} profstart #run: - mtn pcdv 01b72a38e45356d4df0525aec6562e1a6acbf1e1 \ - 53b169c41e5d509dc2bd6d6977e6582ccf78b86d HACKING + mtn pcdv f02571e9d874b48e01921f106107f87257607f0a \ + 6edbbc3496b85a5032fbe0e82347d819a6167206 commands.cc profend #cleanup: popd --- pcdv.cc +++ pcdv.cc @@ -1,10 +1,41 @@ #include #include #include "sanity.hh" #include "pcdv.hh" +#include +unsigned int biggest_living_status=0; +unsigned int sum_living_status=0; +unsigned int num_living_status=0; + +living_status::~living_status() +{ + if (overrides.unique()) + { + ++num_living_status; + sum_living_status+=overrides->size(); + if (overrides->size() > biggest_living_status) + biggest_living_status = overrides->size(); + } +} + +file_state::~file_state() +{ + if (weave.unique()) + { + states.reset(); + std::cout<<"Destroyed file_state of "<size() + <<" lines."< const & a, @@ -174,32 +205,47 @@ living_status living_status::merge(living_status const & other) const { - map > newdict; - for (map >::const_iterator i = overrides.begin(); - i != overrides.end(); ++i) + boost::shared_ptr > > newdict; + newdict.reset(new map >()); + bool notleft=false, notright=false; + for (map >::const_iterator i = overrides->begin(); + i != overrides->end(); ++i) { - newdict.insert(*i); + newdict->insert(*i); map >::const_iterator j = - other.overrides.find(i->first); - I(j == other.overrides.end() || j->second == i->second); + other.overrides->find(i->first); + if (j == other.overrides->end()) + notright = true; + else + I(j->second == i->second); } for (map >::const_iterator i - = other.overrides.begin(); i != other.overrides.end(); ++i) + = other.overrides->begin(); i != other.overrides->end(); ++i) { - newdict.insert(*i); + newdict->insert(*i); map >::const_iterator j - = overrides.find(i->first); - I(j == overrides.end() || j->second == i->second); + = overrides->find(i->first); + if (j == overrides->end()) + notleft = true; + else + I(j->second == i->second); } - return living_status(newdict); + if (!notleft) + return *this; + else if (!notright) + return other; + else + return living_status(newdict); } bool living_status::is_living() const { + if (precomp->first) + return precomp->second; set oldworking, newworking, ref; - for (map >::const_iterator i = overrides.begin(); - i != overrides.end(); ++i) + for (map >::const_iterator i = overrides->begin(); + i != overrides->end(); ++i) ref.insert(i->first); newworking = ref; while (oldworking != newworking) @@ -210,13 +256,14 @@ k != oldworking.end(); ++k) { map >::const_iterator x - = overrides.find(*k); + = overrides->find(*k); for (vector::const_iterator j = x->second.begin(); j != x->second.end(); ++j) newworking.erase(*j); } } - return newworking.find("root") == newworking.end(); + precomp->first = true; + return precomp->second = (newworking.find("root") == newworking.end()); } bool @@ -227,8 +274,8 @@ { result = !result; map >::const_iterator i; - i = overrides.find(key); - if (i == overrides.end() || i->second.empty()) + i = overrides->find(key); + if (i == overrides->end() || i->second.empty()) break; key = idx(i->second, 0); } @@ -241,38 +288,39 @@ if (new_status == is_living()) return *this; set alive; - for (map >::const_iterator i = overrides.begin(); - i != overrides.end(); ++i) + for (map >::const_iterator i = overrides->begin(); + i != overrides->end(); ++i) alive.insert(i->first); - for (map >::const_iterator i = overrides.begin(); - i != overrides.end(); ++i) + for (map >::const_iterator i = overrides->begin(); + i != overrides->end(); ++i) { for (vector::const_iterator j = i->second.begin(); j != i->second.end(); ++j) alive.erase(*j); } - map > newdict(overrides); + boost::shared_ptr > > newdict(overrides); map >::iterator res = - newdict.insert(make_pair(rev, vector())).first; + newdict->insert(make_pair(rev, vector())).first; for (set::iterator i = alive.begin(); i != alive.end(); ++i) { if (_makes_living(*i) != new_status) res->second.push_back(*i); } - return living_status(newdict); + return living_status(newdict, new_status); } -file_state::file_state(vector const & initial, string const & rev) +file_state::file_state(vector const & initial, string const & rev): + states(new map, living_status>()) { weave.reset(new vector > >); for (int i = 0; (unsigned int)(i) < initial.size(); ++i) weave->push_back(make_pair(idx(initial, i), make_pair(rev, i))); for (int i = 0; (unsigned int)(i) < initial.size(); ++i) { - states[make_pair(rev, i)] = living_status().set_living(rev, true); + (*states)[make_pair(rev, i)] = living_status().set_living(rev, true); } } @@ -283,14 +331,14 @@ I(weave == other.weave); file_state newstate(weave); for (map, living_status>::const_iterator i - = states.begin(); i != states.end(); ++i) + = states->begin(); i != states->end(); ++i) { map, living_status>::const_iterator j - = other.states.find(i->first); - if (j != other.states.end()) - newstate.states[i->first] = i->second.merge(j->second); + = other.states->find(i->first); + if (j != other.states->end()) + (*newstate.states)[i->first] = i->second.merge(j->second); else - newstate.states[i->first] = i->second.merge(living_status()); + (*newstate.states)[i->first] = i->second.merge(living_status()); } return newstate; } @@ -304,8 +352,8 @@ = weave->begin(); i != weave->end(); ++i) { map, living_status>::const_iterator j - = states.find(i->second); - if (j != states.end() && j->second.is_living()) + = states->find(i->second); + if (j != states->end() && j->second.is_living()) res.push_back(i->first); } return res; @@ -323,11 +371,11 @@ = weave->begin(); i != weave->end(); ++i) { map, living_status>::const_iterator m - = states.find(i->second); + = states->find(i->second); map, living_status>::const_iterator o - = other.states.find(i->second); - bool mm(m != states.end()); - bool oo(o != other.states.end()); + = other.states->find(i->second); + bool mm(m != states->end()); + bool oo(o != other.states->end()); living_status const & meline(mm?m->second:living_status()); living_status const & otherline(oo?o->second:living_status()); bool mehave = meline.is_living(); @@ -387,8 +435,8 @@ = weave->begin(); i != weave->end(); ++i) { map, living_status>::const_iterator j - = states.find(i->second); - if (j != states.end() && j->second.is_living()) + = states->find(i->second); + if (j != states->end() && j->second.is_living()) lines.push_back(i->first); else lines.push_back(string()); @@ -443,13 +491,66 @@ = weave->begin(); i != weave->end(); ++i) { map, living_status>::const_iterator j - = states.find(i->second); - if (j != states.end()) - out.states[i->second] = j->second.set_living(revision, + = states->find(i->second); + if (j != states->end()) + (*out.states)[i->second] = j->second.set_living(revision, living.find(i->second) != living.end()); else - out.states[i->second] = living_status().set_living(revision, + (*out.states)[i->second] = living_status().set_living(revision, living.find(i->second) != living.end()); } return out; } + +bool +pcdv_test() +{ + vector file; + file_state root(file, "v0"); + file.push_back("line1\n"); + file.push_back("line2\n"); + file.push_back("line3\n"); + file_state file1(root.resolve(file, "v1")); + file[1]="line2 a\n"; + file_state file2a(file1.resolve(file, "v2a")); + file[1]="line2 b\n"; + file_state file2b(file1.resolve(file, "v2b")); + + vector result=file2a.conflict(file2b); + bool lastok=false; + for (vector::iterator i = result.begin(); + i != result.end(); ++i) + { + if (i->split) + { + if (i->left.size()) + { + std::cout<<"<<<<<<<<<<"<<'\n'; + for (vector::iterator j = i->left.begin(); + j != i->left.end(); ++j) + std::cout<<" "<<*j; + } + if (i->right.size()) + { + std::cout<<">>>>>>>>>"<<'\n'; + for (vector::iterator j = i->right.begin(); + j != i->right.end(); ++j) + std::cout<<" "<<*j; + } + lastok = false; + } + else + { + if (i->left.size()) + { + if (!lastok) + std::cout<<"=========="<<'\n'; + for (vector::iterator j = i->left.begin(); + j != i->left.end(); ++j) + std::cout<<" "<<*j; + lastok = true; + } + } + } + return false; +} --- pcdv.hh +++ pcdv.hh @@ -1,9 +1,10 @@ #include #include #include #include #include +#include using std::vector; using std::string; @@ -12,6 +13,9 @@ using std::make_pair; using std::set; +bool +pcdv_test(); + struct merge_section { bool split; @@ -31,19 +35,45 @@ split(true), left(l), right(r) {} }; +// This is a const object type; there are no modifiers. struct living_status { - map > overrides; + boost::shared_ptr > > overrides; + boost::scoped_ptr > precomp; - living_status() + living_status(): + overrides(new map >()), + precomp(new pair(false, false)) { - overrides.insert(make_pair("root", vector())); + overrides->insert(make_pair("root", vector())); } - living_status(map > const & _overrides): - overrides(_overrides) + living_status(boost::shared_ptr > > _overrides): + overrides(_overrides), + precomp(new pair(false, false)) {} + living_status(boost::shared_ptr > > _overrides, + bool living_hint): + overrides(_overrides), + precomp(new pair(true, living_hint)) + {} + + living_status(living_status const & x): + overrides(x.overrides), + precomp(new pair(*x.precomp)) + {} + + living_status const & + operator=(living_status const & x) + { + overrides = x.overrides; + precomp.reset(new pair(*x.precomp)); + return *this; + } + + ~living_status(); + living_status merge(living_status const & other) const; @@ -60,17 +90,21 @@ //a.mash(b).resolve(c) -> "a and b were merged, with result c" //a.mash(b).conflict() -> "merge a and b" //a.resolve(b) -> "b is a child of a" + +// This is a const object type; there are no modifiers. struct file_state { boost::shared_ptr > > > weave; - map, living_status> states; + boost::shared_ptr, living_status> > states; file_state(boost::shared_ptr > > > _weave): - weave(_weave) + weave(_weave), states(new map, living_status>()) {} file_state(vector const & initial, string const & rev); + ~file_state(); + // combine line states between two versions of a file file_state mash(file_state const & other) const;