[Pkg-bazaar-commits] ./bzr-gtk/unstable r20: ignore redundent parents

David Allouche david.allouche at canonical.com
Fri Apr 10 07:15:31 UTC 2009


------------------------------------------------------------
revno: 20
committer: David Allouche <david.allouche at canonical.com>
branch nick: bzrk
timestamp: Sat 2005-11-26 03:03:28 +0100
message:
  ignore redundent parents
modified:
  branchwin.py
  graph.py
-------------- next part --------------
=== modified file 'branchwin.py'
--- a/branchwin.py	2005-10-17 08:23:30 +0000
+++ b/branchwin.py	2005-11-26 02:03:28 +0000
@@ -241,9 +241,10 @@
         index = 0
 
         last_lines = []
-        (revids, self.revisions, colours, self.children) \
+        (revids, self.revisions, colours, self.children, self.parent_ids) \
                  = distances(branch, start)
-        for revision, node, lines in graph(revids, self.revisions, colours):
+        for revision, node, lines in graph(
+                revids, self.revisions, colours, self.parent_ids):
             message = revision.message.split("\n")[0]
             if revision.committer is not None:
                 timestamp = format_date(revision.timestamp, revision.timezone)
@@ -265,7 +266,7 @@
         (path, col) = self.treeview.get_cursor()
         revision = self.model[path][0]
 
-        self.back_button.set_sensitive(len(revision.parent_ids) > 0)
+        self.back_button.set_sensitive(len(self.parent_ids[revision]) > 0)
         self.fwd_button.set_sensitive(len(self.children[revision]) > 0)
 
         if revision.committer is not None:
@@ -286,8 +287,8 @@
             self.table.remove(widget)
 
         self.parents_widgets = []
-        self.table.resize(4 + len(revision.parent_ids) - 1, 2)
-        for idx, parent_id in enumerate(revision.parent_ids):
+        self.table.resize(4 + len(self.parent_ids[revision]) - 1, 2)
+        for idx, parent_id in enumerate(self.parent_ids[revision]):
             self.table.set_row_spacing(idx + 3, 0)
 
             align = gtk.Alignment(0.0, 0.0)
@@ -333,16 +334,16 @@
         """Callback for when the back button is clicked."""
         (path, col) = self.treeview.get_cursor()
         revision = self.model[path][0]
-        if not len(revision.parent_ids):
+        if not len(self.parent_ids[revision]):
             return
 
-        for parent_id in revision.parent_ids:
+        for parent_id in self.parent_ids[revision]:
             parent = self.revisions[parent_id]
             if same_branch(revision, parent):
                 self.treeview.set_cursor(self.index[parent])
                 break
         else:
-            next = self.revisions[revision.parent_ids[0]]
+            next = self.revisions[self.parent_ids[revision][0]]
             self.treeview.set_cursor(self.index[next])
         self.treeview.grab_focus()
 

=== modified file 'graph.py'
--- a/graph.py	2005-10-21 14:01:19 +0000
+++ b/graph.py	2005-11-26 02:03:28 +0000
@@ -58,22 +58,20 @@
 
         found_same = False
         for parent_id in revision.parent_ids:
-            # Check whether there's any point re-processing this
-            if parent_id in distances and distances[parent_id] >= distance:
-                continue
-
             # Get the parent from the cache, or put it in the cache
             try:
                 parent = revisions[parent_id]
-                children[parent].add(revision)
             except KeyError:
                 try:
-                    parent = revisions[parent_id] \
-                             = branch.get_revision(parent_id)
+                    parent = branch.get_revision(parent_id)
                 except NoSuchRevision:
-                    parent = revisions[parent_id] = DummyRevision(parent_id)
+                    parent = DummyRevision(parent_id)
+                revisions[parent_id] = parent
+            children.setdefault(parent, set()).add(revision)
 
-                children[parent] = set([ revision ])
+            # Check whether there's any point re-processing this
+            if parent_id in distances and distances[parent_id] >= distance:
+                continue
 
             # Penalise revisions a little at a fork if we think they're on
             # the same branch -- this makes the few few (at least) revisions
@@ -91,10 +89,62 @@
 
             todo.add(parent_id)
 
-    return ( sorted(distances, key=distances.get), revisions, colours,
-             children )
-
-def graph(revids, revisions, colours):
+    # Topologically sorted revids, with the most recent revisions first
+    sorted_revids = sorted(distances, key=distances.get)
+
+    # Build a parents dictionnary, where redundant parents will be removed, and
+    # that will be passed along tothe rest of program.
+    parent_ids_of = {}
+    for revision in revisions.itervalues():
+        if len(revision.parent_ids) == len(set(revision.parent_ids)):
+            parent_ids_of[revision] = list(revision.parent_ids)
+        else:
+            # remove duplicate parent revisions
+            parent_ids = []
+            parent_ids_set = set()
+            for parent_id in revision.parent_ids:
+                if parent_id in parent_ids_set:
+                    continue
+                parent_ids.append(parent_id)
+                parent_ids_set.add(parent_id)
+            parent_ids_of[revision] = parent_ids
+
+    # Count the number of children of each revision, so we can release memory
+    # for ancestry data as soon as it's not going to be needed anymore.
+    pending_count_of = {}
+    for parent, the_children in children.iteritems():
+        pending_count_of[parent.revision_id] = len(the_children)
+
+    # Build the ancestry dictionnary by examining older revisions first, and
+    # remove revision parents that are ancestors of other parents of the same
+    # revision.
+    ancestor_ids_of = {}
+    for revid in reversed(sorted_revids):
+        revision = revisions[revid]
+        parent_ids = parent_ids_of[revision]
+        # ignore candidate parents which are an ancestor of another parent
+        redundant_ids = []
+        for candidate_id in list(parent_ids):
+            for parent_id in list(parent_ids):
+                if candidate_id in ancestor_ids_of[parent_id]:
+                    redundant_ids.append(candidate_id)
+                    parent_ids.remove(candidate_id)
+                    children_of_candidate = children[revisions[candidate_id]]
+                    children_of_candidate.remove(revision)
+                    break
+        ancestor_ids = set(parent_ids)
+        for parent_id in parent_ids:
+            ancestor_ids.update(ancestor_ids_of[parent_id])
+        for parent_id in parent_ids + redundant_ids:
+            pending_count = pending_count_of[parent_id] - 1
+            pending_count_of[parent_id] = pending_count
+            if pending_count == 0:
+                ancestor_ids_of[parent_id] = None
+        ancestor_ids_of[revid] = ancestor_ids
+
+    return (sorted_revids, revisions, colours, children, parent_ids_of)
+
+def graph(revids, revisions, colours, parent_ids):
     """Produce a directed graph of a bzr branch.
 
     For each revision it then yields a tuple of (revision, node, lines).
@@ -132,7 +182,7 @@
                 # the old column was so anything to the right of this has
                 # to move outwards to make room.  We also try and collapse
                 # hangs to keep the graph small.
-                for parent_id in revisions[revid].parent_ids:
+                for parent_id in parent_ids[revisions[revid]]:
                     try:
                         n_idx = new_hanging.index(parent_id)
                     except ValueError:



More information about the Pkg-bazaar-commits mailing list