Diff
Not logged in

Differences From:

File tools/cvs2fossil/lib/c2f_pbreakacycle.tcl part of check-in [4866889e88] - Continued work on pass 8, added outline for handling of retrograde branches, extended changesets with predicate allowing us to find the branch changesets. by aku on 2007-11-22 03:33:32. [view]

To:

File tools/cvs2fossil/lib/c2f_pbreakacycle.tcl part of check-in [4f1b60dd16] - Continued work on pass 8. Renamed 'retrograde' to 'Backward Branch', should be easier to understand, and completed the predicate testing if a branch changeset is backward or not. by aku on 2007-11-22 03:47:38. [view]

@@ -63,9 +63,9 @@
     typemethod run {} {
 	# Pass manager interface. Executed to perform the
 	# functionality of the pass.
 
-	cyclebreaker precmd   [myproc BreakRetrogradeBranches]
+	cyclebreaker precmd   [myproc BreakBackwardBranches]
 	cyclebreaker savecmd  [myproc SaveOrder]
 	cyclebreaker breakcmd [myproc BreakCycle]
 
 	state transaction {
@@ -107,14 +107,16 @@
     }
 
     # # ## ### ##### ######## #############
 
-    proc BreakRetrogradeBranches {graph} {
+    proc BreakBackwardBranches {graph} {
 	# We go over all branch changesets, i.e. the changesets
 	# created by the symbols which are translated as branches, and
-	# break any which are 'retrograde'. Meaning that they have
-	# incoming revision changesets which are committed after some
-	# outgoing revision changeset.
+	# break any which are 'backward', which means that they have
+	# at least one incoming revision changeset which is committed
+	# after at least one of the outgoing revision changesets, per
+	# the order computed in pass 6. In "cvs2svn" this is called
+	# "retrograde".
 
 	# NOTE: We might be able to use our knowledge that we are
 	# looking at all changesets to create a sql which selects all
 	# the branch changesets from the state in one go instead of
@@ -125,25 +127,64 @@
 	# changesets too ?
 
 	foreach cset [$graph nodes] {
 	    if {![$cset isbranch]} continue
-	    CheckAndBreakRetrograde $graph $cset
+	    CheckAndBreakBackwardBranch $graph $cset
 	}
 	return
     }
 
-    proc CheckAndBreakRetrograde {graph cset} {
-	while {[IsRetrograde $graph $cset]} {
-	    log write 5 breakacycle "Breaking retrograde changeset <[$cset id]>"
+    proc CheckAndBreakBackwardBranch {graph cset} {
+	while {[IsABackwardBranch $graph $cset]} {
+	    log write 5 breakacycle "Breaking backward branch changeset <[$cset id]>"
 
 	    break
 	}
 	return
     }
 
-    proc IsRetrograde {dg cset} {
-	return 0
+    proc IsABackwardBranch {dg cset} {
+	# A branch is "backward" if it has at least one incoming
+	# revision changeset which is committed after at least one of
+	# the outgoing revision changesets, per the order computed in
+	# pass 6.
+
+	# Rephrased, the maximal commit position found among the
+	# incoming revision changesets is larger than the minimal
+	# commit position found among the outgoing revision
+	# changesets. Assuming that we have both incoming and outgoing
+	# revision changesets.
+
+	# The helper "Positions" computes the set of commit positions
+	# for a set of changesets, which can be a mix of revision and
+	# symbol changesets.
+
+	set predecessors [Positions [$dg nodes -in  $cset]]
+	set successors   [Positions [$dg nodes -out $cset]]
+
+	return [expr {
+		      [llength $predecessors] &&
+		      [llength $successors]   &&
+		      ([max $predecessors] >= [min $successors])
+		  }]
+    }
+
+    proc Positions {changesets} {
+	# To compute the set of commit positions from the set of
+	# changesets we first map each changeset to its position (*)
+	# and then filter out the invalid responses (the empty string)
+	# returned by the symbol changesets.
+	#
+	# (*) This data was loaded into memory earlir in the pass, by
+	#     LoadCommitOrder.
+
+	return [struct::list filter [struct::list map $changesets \
+					 [myproc ToPosition]] \
+		    [myproc ValidPosition]]
     }
+
+    proc ToPosition    {cset} { $cset pos }
+    proc ValidPosition {pos}  { expr {$pos ne ""} }
 
     # # ## ### ##### ######## #############
 
     proc SaveOrder {cset pos} {