#
# patch "ChangeLog"
# from [63c759b0cfd48e65dc585981636065a006a2409e]
# to [94df1b3806f6020b5ab486f8e77d0d0789c4c489]
#
# patch "change_set.cc"
# from [39d27129e791256a3b0bba63888179de3fe225c0]
# to [62f13b93026c2ca5cae82595101f98f4fbb05d8e]
#
# patch "pcdv.cc"
# from [3bf2c8965080e804a4f70c0e152ef89f34c9bc03]
# to [52ca638a980086603d40838ebb861e892a5ff7f3]
#
# patch "pcdv.hh"
# from [729ea8ceeea750b9f559fed0403eba28f3270593]
# to [17325b49d29d3b78d11828c7355867d975d63229]
#
========================================================================
--- ChangeLog 63c759b0cfd48e65dc585981636065a006a2409e
+++ ChangeLog 94df1b3806f6020b5ab486f8e77d0d0789c4c489
@@ -1,3 +1,7 @@
+2005-08-20 Timothy Brownawell
+
+ * pcdv.{cc,hh} (tree merger): each file now gets a versioned scalar
+
2005-08-19 Timothy Brownawell
* change_set.cc: Add (and use) dump() for vector
========================================================================
--- change_set.cc 39d27129e791256a3b0bba63888179de3fe225c0
+++ change_set.cc 62f13b93026c2ca5cae82595101f98f4fbb05d8e
@@ -1654,6 +1654,8 @@
file_path left;
file_path right;
file_path merged;
+ bool clean;
+ file_id hash;
itempaths(file_path const & a, file_path const & l,
file_path const & r, file_path const & m):
@@ -1993,6 +1995,7 @@
// do the merge
std::vector conf(l.conflict(r));
+ MM(conf);
std::set res;
for (std::vector::const_iterator i = conf.begin();
i != conf.end(); ++i)
========================================================================
--- pcdv.cc 3bf2c8965080e804a4f70c0e152ef89f34c9bc03
+++ pcdv.cc 52ca638a980086603d40838ebb861e892a5ff7f3
@@ -774,12 +774,18 @@
leaves(),
is_dir(false)
{
- versions->insert(make_pair(revid(-1),
- make_pair(make_pair(item_id(-1),
- make_null_component()),
- vector())));
- std::vector * l = new std::vector();
- l->push_back(revid(-1));
+ versions->first.insert(make_pair(revid(-1),
+ make_pair(make_pair(item_id(-1),
+ make_null_component()),
+ vector())));
+ versions->second.insert(make_pair(revid(-1),
+ make_pair(scalar(-1),
+ vector())));
+ std::pair,
+ std::vector > * l = new std::pair,
+ std::vector >();
+ l->first.push_back(revid(-1));
+ l->second.push_back(revid(-1));
leaves.reset(l);
}
@@ -788,13 +794,19 @@
leaves(),
is_dir(false)
{
- std::vector * l = new std::vector();
- l->push_back(revid(-1));
+ versions->first.insert(make_pair(revid(-1),
+ make_pair(make_pair(item_id(-1),
+ make_null_component()),
+ vector())));
+ versions->second.insert(make_pair(revid(-1),
+ make_pair(scalar(-1),
+ vector())));
+ std::pair,
+ std::vector > * l = new std::pair,
+ std::vector >();
+ l->first.push_back(revid(-1));
+ l->second.push_back(revid(-1));
leaves.reset(l);
- versions->insert(make_pair(revid(-1),
- make_pair(make_pair(item_id(-1),
- make_null_component()),
- vector())));
}
item_status::item_status(item_status const & x):
@@ -810,31 +822,36 @@
item_status::copy() const
{
item_status out(*this);
- out.leaves.reset(new std::vector(*leaves));
+ out.leaves.reset(new std::pair,
+ std::vector >(*leaves));
return out;
}
item_status const
-item_status::new_version(vector const & _leaves) const
+item_status::new_version(std::pair,
+ vector > const & _leaves) const
{
- I(leaves->size());
+ I(leaves->first.size() && leaves->second.size());
item_status out(*this);
- out.leaves.reset(new vector(_leaves));
+ out.leaves.reset(new std::pair,
+ std::vector >(_leaves));
return out;
}
-item_status
-item_status::merge(item_status const & other) const
+template
+vector
+merge_half(std::map > > & versions,
+ std::vector const & leaves1,
+ std::vector const & leaves2)
{
- I(versions == other.versions);
- I(is_dir == other.is_dir);
- set leafset, done;
+ typedef std::map > > data;
+ std::set leafset, done;
std::deque todo;
- for (vector::const_iterator i = leaves->begin();
- i != leaves->end(); ++i)
+ for (vector::const_iterator i = leaves1.begin();
+ i != leaves1.end(); ++i)
leafset.insert(*i);
- for (vector::const_iterator i = other.leaves->begin();
- i != other.leaves->end(); ++i)
+ for (vector::const_iterator i = leaves2.begin();
+ i != leaves2.end(); ++i)
leafset.insert(*i);
for (set::const_iterator i = leafset.begin();
i != leafset.end(); ++i)
@@ -842,8 +859,8 @@
// erase_ancestors(leafset)
while (todo.size())
{
- item_data::const_iterator i = versions->find(todo.front());
- I(i != versions->end());
+ typename data::const_iterator i = versions.find(todo.front());
+ I(i != versions.end());
for (vector::const_iterator j = i->second.second.begin();
j != i->second.second.end(); ++j)
{
@@ -867,6 +884,23 @@
for (set::const_iterator i = leafset.begin();
i != leafset.end(); ++i)
newleaves.push_back(*i);
+ return newleaves;
+}
+
+item_status
+item_status::merge(item_status const & other) const
+{
+ I(versions == other.versions);
+ I(is_dir == other.is_dir);
+ std::vector newleaves1, newleaves2;
+ newleaves1 = merge_half(versions->first,
+ leaves->first,
+ other.leaves->first);
+ newleaves2 = merge_half(versions->second,
+ leaves->second,
+ other.leaves->second);
+ std::pair, std::vector >
+ newleaves(newleaves1, newleaves2);
if (newleaves == *leaves)
return *this;
if (newleaves == *other.leaves)
@@ -874,22 +908,23 @@
return new_version(newleaves);
}
-item_status
-item_status::suture(item_status const & other) const
+template
+void
+suture_maps(std::map > > & v1,
+ std::map > > const & v2)
{
- I(versions != other.versions);
- I(is_dir == other.is_dir);
- for (item_data::iterator o = other.versions->begin();
- o != other.versions->end(); ++o)
+ typedef std::map > > data;
+ for (typename data::const_iterator o = v2.begin();
+ o != v2.end(); ++o)
{
- item_data::iterator m = versions->find(o->first);
- if (m == versions->end())
- versions->insert(*o);
+ typename data::iterator m = v1.find(o->first);
+ if (m == v1.end())
+ v1.insert(*o);
else
{
if (!(m->second.first == o->second.first))
{
- W(F("Sutured items previously had different names in the same revision."));
+ W(F("Sutured items previously had different values in the same revision."));
L(F("This was in revision #%1%") % o->first);
}
std::set s;
@@ -908,23 +943,42 @@
}
}
}
+}
+
+item_status
+item_status::suture(item_status const & other) const
+{
+ I(versions != other.versions);
+ I(is_dir == other.is_dir);
+ suture_maps(versions->first, other.versions->first);
+ suture_maps(versions->second, other.versions->second);
item_status myother(other);
myother.versions = versions;
return merge(myother);
}
-std::set
-item_status::current_names() const
+template
+std::set
+current_values(std::map > > const & v,
+ std::vector const & leaves)
{
- I(leaves->size());
- std::set out;
- for (vector::const_iterator i = leaves->begin();
- i != leaves->end(); ++i)
+ typedef std::map > > data;
+ std::set out;
+ for (typename vector::const_iterator i = leaves.begin();
+ i != leaves.end(); ++i)
{
- item_data::const_iterator j = versions->find(*i);
- I(j != versions->end());
+ typename data::const_iterator j = v.find(*i);
+ I(j != v.end());
out.insert(j->second.first);
}
+ return out;
+}
+
+std::set
+item_status::current_names() const
+{
+ I(leaves->first.size());
+ std::set out = current_values(versions->first, leaves->first);
if (out.size() > 1
&& out.find(make_pair(-1, make_null_component())) != out.end())
{
@@ -934,51 +988,77 @@
return out;
}
-item_status
-item_status::rename(revid rev, item_id new_parent, path_component new_name) const
+std::set
+item_status::current_scalars() const
{
- item_state newstate(make_pair(new_parent, new_name));
+ I(leaves->second.size());
+ return current_values(versions->second, leaves->second);
+}
+
+template
+std::vector
+change_value(std::map > > & ver,
+ std::vector const & leaves, T const & val, revid rev,
+ std::set const & current)
+{
+ typedef std::map > > data;
// {
- item_data::iterator i = versions->find(rev);
- if (i != versions->end())
+ typename data::iterator i = ver.find(rev);
+ if (i != ver.end())
{
// I(i->second.first == newstate);
// An error, but it's triggered by errors already in the monotone db.
// These are of the form cs_left = {}, cs_right = {drop, add}
// So, warn instead of failing.
- if (i->second.first == newstate)
- return *this;
- W(F("Renaming a file to multiple names within one revision."));
+ if (i->second.first == val)
+ return leaves;
+ W(F("Giving a file multiple values within one revision."));
}
// }
- vector newleaves, badleaves;
+ std::vector newleaves, badleaves;
newleaves.push_back(rev);
- for (vector::const_iterator i = leaves->begin();
- i != leaves->end(); ++i)
+ for (vector::const_iterator i = leaves.begin();
+ i != leaves.end(); ++i)
{
- item_data::const_iterator j = versions->find(*i);
- I(j != versions->end());
- if (j->second.first == newstate)
+ typename data::const_iterator j = ver.find(*i);
+ I(j != ver.end());
+ if (j->second.first == val)
newleaves.push_back(*i);
else if (*i != rev)
badleaves.push_back(*i);
}
- if (i != versions->end())
- versions->erase(i);
- versions->insert(make_pair(rev, make_pair(newstate, badleaves)));
+ if (i != ver.end())
+ ver.erase(i);
+ ver.insert(make_pair(rev, make_pair(val, badleaves)));
if (badleaves.empty())
- {
- std::set c = current_names();
- I(c.size() == 1);
- I(*c.begin() == newstate);
- return *this;
- }
+ newleaves.erase(newleaves.begin());
+ return newleaves;
+}
- item_status out(new_version(newleaves));
+item_status
+item_status::rename(revid rev, item_id new_parent, path_component new_name) const
+{
+ path_state newstate(make_pair(new_parent, new_name));
+ std::vector newleaves = change_value(versions->first,
+ leaves->first,
+ newstate,
+ rev, current_names());
+ item_status out(new_version(make_pair(newleaves, leaves->second)));
return out;
}
+item_status
+item_status::set_scalar(revid rev, scalar ns) const
+{
+ std::vector newleaves = change_value(versions->second,
+ leaves->second,
+ ns,
+ rev, current_scalars());
+ item_status out(new_version(make_pair(leaves->first, newleaves)));
+ return out;
+}
+
tree_state::tree_state():
items(new vector >()),
states(new std::map()),
@@ -1166,7 +1246,7 @@
pi = items->size() - 1;
pd = cit.intern(pdir());
outmap.insert(make_pair(pd, pi));
- L(F("New implied directory %1%") % pdir);
+ L(F("New implied directory %1% (%2%)") % pdir % pi);
}
}
@@ -1213,7 +1293,7 @@
for (std::map::const_iterator
j = i->states->begin(); j != i->states->end(); ++j)
{
- std::set s = j->second.current_names();
+ std::set s = j->second.current_names();
I(s.size() == 1);
file_path fp = i->get_full_name(*s.begin());
if ((fp == file_path()))
@@ -1264,7 +1344,9 @@
std::map::const_iterator
j = t.states->find(myid);
I(j != t.states->end());
- file_path fp = t.get_full_name(j->second);
+ std::set s = j->second.current_names();
+ I(s.size() == 1);
+ file_path fp = out.get_full_name(*s.begin());
I(!(fp == file_path()));
done.insert(myid);
std::pair::iterator, bool> r;
@@ -1336,7 +1418,7 @@
I(!(to == file_path()));
{
int d = -1;
- std::set s = current_item.current_names();
+ std::set s = current_item.current_names();
file_path orig;
if (s.size() == 1)
orig = out.try_get_full_name(*s.begin(), d);
@@ -1404,7 +1486,9 @@
std::map::const_iterator
j = t.states->find(myid);
I(j != t.states->end());
- file_path fp = t.get_full_name(j->second);
+ std::set s = j->second.current_names();
+ I(s.size() == 1);
+ file_path fp = out.get_full_name(*s.begin());
I(!(fp == file_path()));
std::pair::iterator, bool> r;
r = outmap.insert(make_pair(cit.intern(fp()), myid));
@@ -1472,14 +1556,14 @@
apply_sutures();
tree_state merged(mash(other));
std::vector out;
- std::map > m;
+ std::map > m;
// splits, merge(mv a b, mv a c)
for (std::map::const_iterator
i = merged.states->begin();
i != merged.states->end(); ++i)
{
- std::set s = i->second.current_names();
+ std::set s = i->second.current_names();
if (s.size() != 1)
{
path_conflict c;
@@ -1490,7 +1574,7 @@
k(other.states->find(i->first));
I(j != states->end());
I(k != other.states->end());
- std::set
+ std::set
left(j->second.current_names()),
right(k->second.current_names());
I(left.size() == 1);
@@ -1499,12 +1583,12 @@
c.rnames.push_back(other.get_full_name(*right.begin()));
out.push_back(c);
}
- for (std::set::const_iterator
+ for (std::set::const_iterator
j = s.begin(); j != s.end(); ++j)
{
if (*j == make_pair(item_id(-1), make_null_component()))
continue;
- std::map >::iterator
+ std::map >::iterator
k = m.find(*j);
if (k == m.end())
{
@@ -1518,7 +1602,7 @@
}
// collisions, merge(mv a c, mv b c)
- for (std::map >::const_iterator
+ for (std::map >::const_iterator
i = m.begin(); i != m.end(); ++i)
{
if (i->second.size() == 1)
@@ -1533,7 +1617,7 @@
std::map::const_iterator
l(states->find(*j)),
r(other.states->find(*j));
- std::set left, right;
+ std::set left, right;
if (l != states->end())
{
left = l->second.current_names();
@@ -1566,9 +1650,7 @@
{
if (i->second.is_dir)
continue;
- std::set s = i->second.current_names();
- I(s.size() == 1);
- file_path fp = get_full_name(*s.begin());
+ file_path fp = get_full_name(i->second);
if (!(fp == file_path()))
out.push_back(make_pair(i->first, fp));
}
@@ -1583,9 +1665,7 @@
for (std::map::const_iterator i = states->begin();
i != states->end(); ++i)
{
- std::set s = i->second.current_names();
- I(s.size() == 1);
- file_path fp = get_full_name(*s.begin());
+ file_path fp = get_full_name(i->second);
if (!(fp == file_path()))
out.push_back(make_pair(i->first, fp));
}
@@ -1609,12 +1689,12 @@
map::const_iterator l, r;
l = states->begin();
r = merged.states->begin();
- item_status::item_state empty(-1, make_null_component());
+ item_status::path_state empty(-1, make_null_component());
while (l != states->end() || r != merged.states->end())
{
file_path from, to;
- std::set pres, posts;
- item_status::item_state pre(empty), post(empty);
+ std::set pres, posts;
+ item_status::path_state pre(empty), post(empty);
bool from_is_dir(false), to_is_dir(false);
if (l == states->end())
@@ -1742,7 +1822,7 @@
{
if (resolved.find(j->first) == resolved.end())
{
- std::set
+ std::set
x(j->second.current_names());
if (x.size() != 1)
continue;// not resolved, so not closer
@@ -1775,7 +1855,7 @@
if (s == resolved.size())
{
// already resolved this item, this resolution had better match
- std::set names = it.current_names();
+ std::set names = it.current_names();
I(names.size() == 1);
file_path prev = merged.get_full_name(*names.begin());
file_path to;
@@ -1840,14 +1920,14 @@
file_path
tree_state::get_full_name(item_status x) const
{
- std::set y;
+ std::set y;
y = x.current_names();
I(y.size() == 1);
return get_full_name(*y.begin());
}
file_path
-tree_state::get_full_name(item_status::item_state x) const
+tree_state::get_full_name(item_status::path_state x) const
{
int d;
file_path out(try_get_full_name(x, d));
@@ -1856,7 +1936,7 @@
}
file_path
-tree_state::try_get_full_name(item_status::item_state x, int & d) const
+tree_state::try_get_full_name(item_status::path_state x, int & d) const
{
d = 0;
std::vector names;
@@ -1866,7 +1946,7 @@
std::map::const_iterator
i = states->find(x.first);
I(i != states->end());
- std::set y = i->second.current_names();
+ std::set y = i->second.current_names();
if (y.size() != 1)
{
d = -1;
@@ -1882,7 +1962,7 @@
}
std::string
-tree_state::get_ambiguous_full_name(item_status::item_state x) const
+tree_state::get_ambiguous_full_name(item_status::path_state x) const
{
// fails if the item has multiple names (only call this on clean trees)
std::vector names;
@@ -1894,7 +1974,7 @@
std::map::const_iterator
i = states->find(x.first);
I(i != states->end());
- std::set y = i->second.current_names();
+ std::set y = i->second.current_names();
if (y.size() != 1)
{
out = (F("/") % x.first).str();
@@ -1909,10 +1989,71 @@
return out;
}
+tree_state
+tree_state::set_scalars(std::string revision,
+ std::map const & m) const
+{
+ apply_sutures();
+ tree_state out(*this);
+ std::vector > c = current_with_dirs();
+ for (std::vector >::const_iterator
+ i = c.begin(); i != c.end(); ++i)
+ {
+ std::map::const_iterator
+ j = m.find(i->second);
+ if (j == m.end())
+ continue;
+ std::map::iterator k = out.states->find(i->first);
+ I(k != out.states->end());
+ k->second = k->second.set_scalar(itx->intern(revision), j->second);
+ }
+ return out;
+}
+std::map >
+tree_state::current_scalars() const
+{
+ apply_sutures();
+ std::map > out;
+ for (std::map::const_iterator i = states->begin();
+ i != states->end(); ++i)
+ out.insert(make_pair(i->first, i->second.current_scalars()));
+ return out;
+}
+//////////////////////////// I/O ////////////////////////////////////
+
+void
+dump(path_conflict const & obj, std::string & out)
+{
+ out = "##########";
+ out+=(F("#Type: %1%\n")
+ % ((obj.type == path_conflict::collision)?"Collision":"Split")).str();
+ for (unsigned int j = 0; j < obj.items.size(); ++j)
+ {
+ out+=(F("Item %1%:\n") % idx(obj.items, j)).str();
+ out+=(F("#\tLname: %1%\n") % idx(obj.lnames, j)).str();
+ out+=(F("#\tRname: %1%\n") % idx(obj.rnames, j)).str();
+ }
+ out+=(F("#Name: %1%\n") % obj.name).str();
+}
+
+void
+dump(std::vector const & obj, std::string & out)
+{
+ out.clear();
+ for (std::vector::const_iterator i = obj.begin();
+ i != obj.end(); ++i)
+ {
+ std::string tmp;
+ dump(*i, tmp);
+ out += tmp;
+ }
+}
+
+
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/////////////////////////// Tests ///////////////////////////////////
========================================================================
--- pcdv.hh 729ea8ceeea750b9f559fed0403eba28f3270593
+++ pcdv.hh 17325b49d29d3b78d11828c7355867d975d63229
@@ -193,12 +193,16 @@
struct item_status
{
- typedef std::pair item_state;
- typedef std::map > > item_data;
+ typedef unsigned int scalar;
+ typedef std::pair path_state;
+ typedef std::map > > path_data;
+ typedef std::map > > scalar_data;
+ typedef std::pair item_data;
// shared for all versions of this item
boost::shared_ptr versions;
// shared between all copies of this version of this item
- boost::shared_ptr const > leaves;
+ boost::shared_ptr,
+ std::vector > const> leaves;
bool is_dir;
item_status();
@@ -208,7 +212,8 @@
~item_status();
item_status const
- new_version(vector const & _leaves) const;
+ new_version(std::pair,
+ std::vector > const & _leaves) const;
item_status
merge(item_status const & other) const;
@@ -216,13 +221,19 @@
item_status
suture(item_status const & other) const;
- std::set
+ std::set
current_names() const;
+ std::set
+ current_scalars() const;
+
item_status
rename(revid rev, item_id new_parent, path_component new_name) const;
item_status
+ set_scalar(revid rev, scalar ns) const;
+
+ item_status
copy() const;
};
@@ -268,8 +279,15 @@
std::vector const & changes,
std::string revision);
+ tree_state
+ set_scalars(std::string revision,
+ std::map const & m) const;
+
std::vector
conflict(tree_state const & other) const;
+
+ std::map >
+ current_scalars() const;
bool
is_clean()
@@ -292,16 +310,16 @@
std::string const & revision);
private:
file_path
- get_full_name(item_status::item_state x) const;
+ get_full_name(item_status::path_state x) const;
file_path
get_full_name(item_status x) const;
file_path
- try_get_full_name(item_status::item_state x, int & d) const;
+ try_get_full_name(item_status::path_state x, int & d) const;
std::string
- get_ambiguous_full_name(item_status::item_state x) const;
+ get_ambiguous_full_name(item_status::path_state x) const;
tree_state
mash(tree_state const & other) const;
@@ -317,6 +335,12 @@
};
void
+dump(path_conflict const & obj, std::string & out);
+
+void
+dump(std::vector const & obj, std::string & out);
+
+void
dirmerge_test();
#endif