#
#
# patch "ChangeLog"
# from [ce11cd3ab433ce9fe8c1645321267dc93865514e]
# to [75b4a58f05b4c01f9386cd1952b9d08b52e9d06d]
#
# patch "annotate.cc"
# from [5a0e7200fad7865dc1ce9b30aaa531d0f6f7b542]
# to [50b054150a5d9cdc0902867573202c2adbddab50]
#
# patch "database.cc"
# from [a65fbb52f8ad90194b9c195ee5e3c16e2113e5e9]
# to [8fd5626b20edcf5ebcd042ad36d8f9b3202ead44]
#
# patch "database.hh"
# from [90abb4ec87c1b090257a07d79be1c3e33d931a6a]
# to [d3e1ec3863d5a86422a4fb4fad90925392c2437c]
#
# patch "roster_delta.cc"
# from [66a0a455754209bea533db586769e37b9bd18ca3]
# to [c78fd99ec874ac047c4c5b2581f8e974a1adf648]
#
# patch "roster_delta.hh"
# from [25e389e2c42e9754480cb7f5e43157623eeaf1fa]
# to [c469955ebc623dd5986883c7751a1010e530a963]
#
============================================================
--- ChangeLog ce11cd3ab433ce9fe8c1645321267dc93865514e
+++ ChangeLog 75b4a58f05b4c01f9386cd1952b9d08b52e9d06d
@@ -1,3 +1,20 @@
+2007-02-02 Thomas Moschny
+
+ * roster_delta.{cc|hh}
+ (get_markings_from_roster_delta, get_content_from_roster_delta):
+ New functions. Both try to extract node-specific information from
+ a single roster delta.
+
+ * database.{cc|hh} (get_markings, get_file_content): New functions
+ using roster deltas to find the set of markings resp. the content
+ hash for a given node and revision id.
+
+ * annotate.cc (do_annotate_node): Utilize the new methods. Store
+ the set of markings and the file content hash in the work_unit for
+ the corresponding revision, to avoid fetching the same information
+ twice. Don't fetch content hash or markings for marked ancestors,
+ as we can deduce that information from the descendants.
+
2007-02-01 Matthew Gregan
* sqlite/*: Import SQLite 3.3.12.
============================================================
--- annotate.cc 5a0e7200fad7865dc1ce9b30aaa531d0f6f7b542
+++ annotate.cc 50b054150a5d9cdc0902867573202c2adbddab50
@@ -160,12 +160,16 @@ struct annotate_node_work
annotate_node_work(shared_ptr annotations_,
shared_ptr lineage_,
revision_id revision_, node_id fid_,
- rev_height height_)
+ rev_height height_,
+ shared_ptr > content_marks_,
+ file_id content_)
: annotations(annotations_),
lineage(lineage_),
revision(revision_),
fid(fid_),
- height(height_)
+ height(height_),
+ content_marks(content_marks_),
+ content(content_)
{}
shared_ptr annotations;
@@ -173,6 +177,8 @@ struct annotate_node_work
revision_id revision;
node_id fid;
rev_height height;
+ shared_ptr > content_marks;
+ file_id content;
};
struct by_rev {};
@@ -662,6 +668,23 @@ annotate_lineage_mapping::set_copied_all
}
}
+// fetches the list of file_content markings for the given revision_id and
+// node_id
+static void get_file_content_marks(app_state & app,
+ revision_id const & rev,
+ node_id const & fid,
+ set & content_marks)
+{
+ marking_t markings;
+ app.db.get_markings(rev, fid, markings);
+
+ I(markings.file_content.size() != 0);
+
+ content_marks.clear();
+ content_marks.insert(markings.file_content.begin(),
+ markings.file_content.end());
+}
+
static void
do_annotate_node
(annotate_node_work const & work_unit,
@@ -670,66 +693,60 @@ do_annotate_node
{
L(FL("do_annotate_node for node %s") % work_unit.revision);
- roster_t roster;
- marking_t marks;
+ shared_ptr > ancestors;
- {
- marking_map markmap;
- app.db.get_roster(work_unit.revision, roster, markmap);
-
- map::const_iterator mmi =
- markmap.find(work_unit.fid);
- I(mmi != markmap.end());
- marks = mmi->second;
- }
-
- I(marks.file_content.size() != 0);
-
- set parents; // fixme: rename
-
- if (marks.file_content.size() == 1
- && *(marks.file_content.begin()) == work_unit.revision)
+ bool marked = (work_unit.content_marks->size() == 1
+ && *(work_unit.content_marks->begin()) == work_unit.revision);
+
+ if (marked)
{
+ ancestors = shared_ptr > (new set());
// this node is marked, need to inspect the parents
- app.db.get_revision_parents(work_unit.revision, parents);
+ app.db.get_revision_parents(work_unit.revision, *ancestors);
}
else
{
- // jump directly to the marked ancestors
- parents = marks.file_content;
+ ancestors = work_unit.content_marks;
}
size_t added_in_parent_count = 0;
- for (set::const_iterator i = parents.begin();
- i != parents.end(); i++)
+ for (set::const_iterator i = ancestors->begin();
+ i != ancestors->end(); i++)
{
revision_id parent_revision = *i;
- roster_t parent_roster;
L(FL("do_annotate_node processing edge from parent %s to child %s")
% parent_revision % work_unit.revision);
I(!(work_unit.revision == parent_revision));
- app.db.get_roster(parent_revision, parent_roster);
- if (!parent_roster.has_node(work_unit.fid))
+ file_id file_in_parent;
+ shared_ptr > parent_content_marks(new set());
+
+ if (marked)
{
- L(FL("file added in %s, continuing") % work_unit.revision);
- added_in_parent_count++;
- continue;
+ // we are marked, so we don't know much about the ancestor
+ app.db.get_file_content(parent_revision, work_unit.fid, file_in_parent);
+ if (null_id(file_in_parent))
+ {
+ L(FL("file added in %s, continuing") % work_unit.revision);
+ added_in_parent_count++;
+ continue;
+ }
+ get_file_content_marks(app, parent_revision, work_unit.fid, *parent_content_marks);
}
-
+ else
+ {
+ // we know that this ancestor is marked
+ file_in_parent = work_unit.content;
+ parent_content_marks->insert(parent_revision);
+ }
+
// The node was live in the parent, so this represents a delta.
- file_t file_in_child =
- downcast_to_file_t(roster.get_node(work_unit.fid));
-
- file_t file_in_parent =
- downcast_to_file_t(parent_roster.get_node(work_unit.fid));
-
shared_ptr parent_lineage;
- if (file_in_parent->content == file_in_child->content)
+ if (file_in_parent == work_unit.content)
{
L(FL("parent file identical, "
"set copied all mapped and copy lineage\n"));
@@ -739,9 +756,9 @@ do_annotate_node
else
{
file_data data;
- app.db.get_file_version(file_in_parent->content, data);
+ app.db.get_file_version(file_in_parent, data);
L(FL("building parent lineage for parent file %s")
- % file_in_parent->content);
+ % file_in_parent);
parent_lineage
= work_unit.lineage->build_parent_lineage(work_unit.annotations,
parent_revision,
@@ -763,7 +780,9 @@ do_annotate_node
parent_lineage,
parent_revision,
work_unit.fid,
- parent_height);
+ parent_height,
+ parent_content_marks,
+ file_in_parent);
work_units.insert(newunit);
}
@@ -777,7 +796,7 @@ do_annotate_node
}
}
- if (added_in_parent_count == parents.size())
+ if (added_in_parent_count == ancestors->size())
{
work_unit.lineage->credit_mapped_lines(work_unit.annotations);
}
@@ -799,9 +818,13 @@ do_annotate (app_state &app, file_t file
work_units work_units;
{
+ // prepare the first work_unit
rev_height height;
app.db.get_rev_height(rid, height);
- annotate_node_work workunit(acp, lineage, rid, file_node->self, height);
+ shared_ptr >content_marks(new set());
+ get_file_content_marks(app, rid, file_node->self, *content_marks);
+ annotate_node_work workunit(acp, lineage, rid, file_node->self, height,
+ content_marks, file_node->content);
work_units.insert(workunit);
}
============================================================
--- database.cc a65fbb52f8ad90194b9c195ee5e3c16e2113e5e9
+++ database.cc 8fd5626b20edcf5ebcd042ad36d8f9b3202ead44
@@ -1395,6 +1395,130 @@ void
};
void
+database::get_markings(revision_id const & id,
+ node_id const & nid,
+ marking_t & markings)
+{
+ reconstruction_path selected_path;
+ {
+ roster_reconstruction_graph graph(*this);
+ {
+ // we look at the nearest delta(s) first, without constructing the
+ // whole path, as this is rather expensive
+ set deltas;
+ graph.get_next(id.inner()(), deltas);
+ for (set::const_iterator i = deltas.begin();
+ i != deltas.end(); ++i)
+ {
+ roster_delta del;
+ get_roster_delta(id.inner()(), *i, del);
+ bool found = get_markings_from_roster_delta(del, nid, markings);
+ if (found)
+ return;
+ }
+ }
+ get_reconstruction_path(id.inner()(), graph, selected_path);
+ }
+
+ int path_length(selected_path.size());
+ int i(0);
+ string target_rev;
+
+ for (reconstruction_path::const_iterator p = selected_path.begin();
+ p != selected_path.end(); ++p)
+ {
+ if (i > 0)
+ {
+ roster_delta del;
+ get_roster_delta(target_rev, *p, del);
+ bool found = get_markings_from_roster_delta(del, nid, markings);
+ if (found)
+ return;
+ }
+ if (i == path_length-1)
+ {
+ // last iteration, we have reached a roster base
+ roster_t roster;
+ marking_map mm;
+ get_roster_base(*p, roster, mm);
+ map::const_iterator mmi =
+ mm.find(nid);
+ I(mmi != mm.end());
+ markings = mmi->second;
+ return;
+ }
+ target_rev = *p;
+ ++i;
+ }
+}
+
+void
+database::get_file_content(revision_id const & id,
+ node_id const & nid,
+ file_id & content)
+{
+ // the imaginary root revision doesn't have any file.
+ if (null_id(id))
+ {
+ content = file_id();
+ return;
+ }
+
+ reconstruction_path selected_path;
+ {
+ roster_reconstruction_graph graph(*this);
+ {
+ // we look at the nearest delta(s) first, without constructing the
+ // whole path, as this is rather expensive
+ set deltas;
+ graph.get_next(id.inner()(), deltas);
+ for (set::const_iterator i = deltas.begin();
+ i != deltas.end(); ++i)
+ {
+ roster_delta del;
+ get_roster_delta(id.inner()(), *i, del);
+ bool found = get_content_from_roster_delta(del, nid, content);
+ if (found)
+ return;
+ }
+ }
+ get_reconstruction_path(id.inner()(), graph, selected_path);
+ }
+
+ int path_length(selected_path.size());
+ int i(0);
+ string target_rev;
+
+ for (reconstruction_path::const_iterator p = selected_path.begin();
+ p != selected_path.end(); ++p)
+ {
+ if (i > 0)
+ {
+ roster_delta del;
+ get_roster_delta(target_rev, *p, del);
+ bool found = get_content_from_roster_delta(del, nid, content);
+ if (found)
+ return;
+ }
+ if (i == path_length-1)
+ {
+ // last iteration, we have reached a roster base
+ roster_t roster;
+ marking_map mm;
+ get_roster_base(*p, roster, mm);
+ if (roster.has_node(nid))
+ content = downcast_to_file_t(roster.get_node(nid))->content;
+ else
+ content = file_id();
+ return;
+ }
+ target_rev = *p;
+ ++i;
+ }
+}
+
+
+void
database::get_roster_version(revision_id const & id,
cached_roster & cr)
{
============================================================
--- database.hh 90abb4ec87c1b090257a07d79be1c3e33d931a6a
+++ database.hh d3e1ec3863d5a86422a4fb4fad90925392c2437c
@@ -349,6 +349,15 @@ public:
bool roster_version_exists(revision_id const & ident);
void get_roster_ids(std::set & ids);
+ // using roster deltas
+ void get_markings(revision_id const & id,
+ node_id const & nid,
+ marking_t & markings);
+
+ void get_file_content(revision_id const & id,
+ node_id const & nid,
+ file_id & content);
+
//
// --== Keys ==--
//
============================================================
--- roster_delta.cc 66a0a455754209bea533db586769e37b9bd18ca3
+++ roster_delta.cc c78fd99ec874ac047c4c5b2581f8e974a1adf648
@@ -491,7 +491,62 @@ apply_roster_delta(roster_delta const &
d.apply(roster, markings);
}
+// Extract the marking for one node from the roster delta, or return false
+// if they are not contained in that delta
+bool
+get_markings_from_roster_delta(roster_delta const & del,
+ node_id const & nid,
+ marking_t & markings)
+{
+ // FIXME: factor out this block
+ basic_io::input_source src(del.inner()(), "roster_delta");
+ basic_io::tokenizer tok(src);
+ basic_io::parser pars(tok);
+ roster_delta_t d;
+ parse_roster_delta_t(pars, d);
+ std::map::iterator i = d.markings_changed.find(nid);
+ if (i != d.markings_changed.end())
+ {
+ markings = i->second;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+// Extract the content hash for one node from the roster delta. Return false
+// if this delta doesn't contain information about this node.
+bool
+get_content_from_roster_delta(roster_delta const & del,
+ node_id const & nid,
+ file_id & content)
+{
+ // FIXME: factor out this block
+ basic_io::input_source src(del.inner()(), "roster_delta");
+ basic_io::tokenizer tok(src);
+ basic_io::parser pars(tok);
+ roster_delta_t d;
+ parse_roster_delta_t(pars, d);
+
+ std::map::const_iterator i = d.deltas_applied.find(nid);
+ if (i != d.deltas_applied.end())
+ {
+ content = i->second;
+ return true;
+ }
+
+ if (d.nodes_deleted.find(nid) != d.nodes_deleted.end())
+ {
+ content = file_id();
+ return true;
+ }
+
+ return false;
+}
+
#ifdef BUILD_UNIT_TESTS
static void
============================================================
--- roster_delta.hh 25e389e2c42e9754480cb7f5e43157623eeaf1fa
+++ roster_delta.hh c469955ebc623dd5986883c7751a1010e530a963
@@ -25,7 +25,16 @@ apply_roster_delta(roster_delta const &
apply_roster_delta(roster_delta const & del,
roster_t & roster, marking_map & markings);
+bool
+get_markings_from_roster_delta(roster_delta const & del,
+ node_id const & nid,
+ marking_t & markings);
+bool
+get_content_from_roster_delta(roster_delta const & del,
+ node_id const & nid,
+ file_id & content);
+
#ifdef BUILD_UNIT_TESTS
// instead of having elaborate tests here, we just export a function, and then