e7c805f137 2007-11-16 aku: ## -*- tcl -*- e7c805f137 2007-11-16 aku: # # ## ### ##### ######## ############# ##################### e7c805f137 2007-11-16 aku: ## Copyright (c) 2007 Andreas Kupries. e7c805f137 2007-11-16 aku: # e7c805f137 2007-11-16 aku: # This software is licensed as described in the file LICENSE, which e7c805f137 2007-11-16 aku: # you should have received as part of this distribution. e7c805f137 2007-11-16 aku: # e7c805f137 2007-11-16 aku: # This software consists of voluntary contributions made by many e7c805f137 2007-11-16 aku: # individuals. For exact contribution history, see the revision e7c805f137 2007-11-16 aku: # history and logs, available at http://fossil-scm.hwaci.com/fossil e7c805f137 2007-11-16 aku: # # ## ### ##### ######## ############# ##################### e7c805f137 2007-11-16 aku: e7c805f137 2007-11-16 aku: ## Pass VIII. This is the final pass for breaking changeset dependency e7c805f137 2007-11-16 aku: ## cycles. The two previous passes broke cycles covering revision and e7c805f137 2007-11-16 aku: ## symbol changesets, respectively. This pass now breaks any remaining e7c805f137 2007-11-16 aku: ## cycles each of which has to contain at least one revision and at e7c805f137 2007-11-16 aku: ## least one symbol changeset. e7c805f137 2007-11-16 aku: e7c805f137 2007-11-16 aku: # # ## ### ##### ######## ############# ##################### e7c805f137 2007-11-16 aku: ## Requirements e7c805f137 2007-11-16 aku: e7c805f137 2007-11-16 aku: package require Tcl 8.4 ; # Required runtime. e7c805f137 2007-11-16 aku: package require snit ; # OO system. e7c805f137 2007-11-16 aku: package require struct::list ; # Higher order list operations. 4866889e88 2007-11-22 aku: package require vc::tools::misc ; # Min, max. e7c805f137 2007-11-16 aku: package require vc::tools::log ; # User feedback. 4866889e88 2007-11-22 aku: package require vc::tools::trouble ; # Error reporting. 1f60018119 2007-11-21 aku: package require vc::fossil::import::cvs::repository ; # Repository management. e7c805f137 2007-11-16 aku: package require vc::fossil::import::cvs::cyclebreaker ; # Breaking dependency cycles. e7c805f137 2007-11-16 aku: package require vc::fossil::import::cvs::state ; # State storage. e7c805f137 2007-11-16 aku: package require vc::fossil::import::cvs::project::rev ; # Project level changesets e7c805f137 2007-11-16 aku: e7c805f137 2007-11-16 aku: # # ## ### ##### ######## ############# ##################### e7c805f137 2007-11-16 aku: ## Register the pass with the management e7c805f137 2007-11-16 aku: e7c805f137 2007-11-16 aku: vc::fossil::import::cvs::pass define \ e7c805f137 2007-11-16 aku: BreakAllCsetCycles \ e7c805f137 2007-11-16 aku: {Break Remaining ChangeSet Dependency Cycles} \ e7c805f137 2007-11-16 aku: ::vc::fossil::import::cvs::pass::breakacycle e7c805f137 2007-11-16 aku: e7c805f137 2007-11-16 aku: # # ## ### ##### ######## ############# ##################### e7c805f137 2007-11-16 aku: ## e7c805f137 2007-11-16 aku: e7c805f137 2007-11-16 aku: snit::type ::vc::fossil::import::cvs::pass::breakacycle { e7c805f137 2007-11-16 aku: # # ## ### ##### ######## ############# e7c805f137 2007-11-16 aku: ## Public API e7c805f137 2007-11-16 aku: e7c805f137 2007-11-16 aku: typemethod setup {} { e7c805f137 2007-11-16 aku: # Define the names and structure of the persistent state of e7c805f137 2007-11-16 aku: # this pass. de4cff4142 2007-11-22 aku: de4cff4142 2007-11-22 aku: state reading csorder e7c805f137 2007-11-16 aku: return e7c805f137 2007-11-16 aku: } e7c805f137 2007-11-16 aku: e7c805f137 2007-11-16 aku: typemethod load {} { e7c805f137 2007-11-16 aku: # Pass manager interface. Executed to load data computed by e7c805f137 2007-11-16 aku: # this pass into memory when this pass is skipped instead of e7c805f137 2007-11-16 aku: # executed. e7c805f137 2007-11-16 aku: return e7c805f137 2007-11-16 aku: } e7c805f137 2007-11-16 aku: e7c805f137 2007-11-16 aku: typemethod run {} { e7c805f137 2007-11-16 aku: # Pass manager interface. Executed to perform the e7c805f137 2007-11-16 aku: # functionality of the pass. 7f15be9078 2007-11-20 aku: 4f1b60dd16 2007-11-22 aku: cyclebreaker precmd [myproc BreakBackwardBranches] 1f60018119 2007-11-21 aku: cyclebreaker savecmd [myproc SaveOrder] 1f60018119 2007-11-21 aku: cyclebreaker breakcmd [myproc BreakCycle] 1f60018119 2007-11-21 aku: 1f60018119 2007-11-21 aku: state transaction { de4cff4142 2007-11-22 aku: LoadCommitOrder 1f60018119 2007-11-21 aku: cyclebreaker run break-all [myproc Changesets] 1f60018119 2007-11-21 aku: } 1f60018119 2007-11-21 aku: 1f60018119 2007-11-21 aku: repository printcsetstatistics e7c805f137 2007-11-16 aku: return e7c805f137 2007-11-16 aku: } e7c805f137 2007-11-16 aku: e7c805f137 2007-11-16 aku: typemethod discard {} { e7c805f137 2007-11-16 aku: # Pass manager interface. Executed for all passes after the e7c805f137 2007-11-16 aku: # run passes, to remove all data of this pass from the state, e7c805f137 2007-11-16 aku: # as being out of date. e7c805f137 2007-11-16 aku: return e7c805f137 2007-11-16 aku: } e7c805f137 2007-11-16 aku: e7c805f137 2007-11-16 aku: # # ## ### ##### ######## ############# e7c805f137 2007-11-16 aku: ## Internal methods e7c805f137 2007-11-16 aku: 2a0ec504c5 2007-11-21 aku: proc Changesets {} { project::rev all } 2a0ec504c5 2007-11-21 aku: de4cff4142 2007-11-22 aku: proc LoadCommitOrder {} { de4cff4142 2007-11-22 aku: ::variable mycset de4cff4142 2007-11-22 aku: de4cff4142 2007-11-22 aku: state transaction { de4cff4142 2007-11-22 aku: foreach {cid pos} [state run { SELECT cid, pos FROM csorder }] { de4cff4142 2007-11-22 aku: set cset [project::rev of $cid] de4cff4142 2007-11-22 aku: $cset setpos $pos de4cff4142 2007-11-22 aku: set mycset($pos) $cset de4cff4142 2007-11-22 aku: } de4cff4142 2007-11-22 aku: # Remove the order information now that we have it in de4cff4142 2007-11-22 aku: # memory, so that we can save it once more, for all de4cff4142 2007-11-22 aku: # changesets, while breaking the remaining cycles. de4cff4142 2007-11-22 aku: state run { DELETE FROM csorder } de4cff4142 2007-11-22 aku: } de4cff4142 2007-11-22 aku: return de4cff4142 2007-11-22 aku: } de4cff4142 2007-11-22 aku: 1f60018119 2007-11-21 aku: # # ## ### ##### ######## ############# 1f60018119 2007-11-21 aku: 4f1b60dd16 2007-11-22 aku: proc BreakBackwardBranches {graph} { 4866889e88 2007-11-22 aku: # We go over all branch changesets, i.e. the changesets 4866889e88 2007-11-22 aku: # created by the symbols which are translated as branches, and 4f1b60dd16 2007-11-22 aku: # break any which are 'backward', which means that they have 4f1b60dd16 2007-11-22 aku: # at least one incoming revision changeset which is committed 4f1b60dd16 2007-11-22 aku: # after at least one of the outgoing revision changesets, per 4f1b60dd16 2007-11-22 aku: # the order computed in pass 6. In "cvs2svn" this is called 4f1b60dd16 2007-11-22 aku: # "retrograde". 4866889e88 2007-11-22 aku: 4866889e88 2007-11-22 aku: # NOTE: We might be able to use our knowledge that we are 4866889e88 2007-11-22 aku: # looking at all changesets to create a sql which selects all 4866889e88 2007-11-22 aku: # the branch changesets from the state in one go instead of 4866889e88 2007-11-22 aku: # having to check each changeset separately. Consider this 4866889e88 2007-11-22 aku: # later, get the pass working first. 4866889e88 2007-11-22 aku: # 4866889e88 2007-11-22 aku: # NOTE 2: Might we even be able to select the retrograde 4866889e88 2007-11-22 aku: # changesets too ? 4866889e88 2007-11-22 aku: 4866889e88 2007-11-22 aku: foreach cset [$graph nodes] { 4866889e88 2007-11-22 aku: if {![$cset isbranch]} continue 4f1b60dd16 2007-11-22 aku: CheckAndBreakBackwardBranch $graph $cset 4866889e88 2007-11-22 aku: } 4866889e88 2007-11-22 aku: return 4866889e88 2007-11-22 aku: } 4866889e88 2007-11-22 aku: 4f1b60dd16 2007-11-22 aku: proc CheckAndBreakBackwardBranch {graph cset} { 4f1b60dd16 2007-11-22 aku: while {[IsABackwardBranch $graph $cset]} { 4f1b60dd16 2007-11-22 aku: log write 5 breakacycle "Breaking backward branch changeset <[$cset id]>" 4866889e88 2007-11-22 aku: 4866889e88 2007-11-22 aku: break 4866889e88 2007-11-22 aku: } 4866889e88 2007-11-22 aku: return 4866889e88 2007-11-22 aku: } 4866889e88 2007-11-22 aku: 4f1b60dd16 2007-11-22 aku: proc IsABackwardBranch {dg cset} { 4f1b60dd16 2007-11-22 aku: # A branch is "backward" if it has at least one incoming 4f1b60dd16 2007-11-22 aku: # revision changeset which is committed after at least one of 4f1b60dd16 2007-11-22 aku: # the outgoing revision changesets, per the order computed in 4f1b60dd16 2007-11-22 aku: # pass 6. 4f1b60dd16 2007-11-22 aku: 4f1b60dd16 2007-11-22 aku: # Rephrased, the maximal commit position found among the 4f1b60dd16 2007-11-22 aku: # incoming revision changesets is larger than the minimal 4f1b60dd16 2007-11-22 aku: # commit position found among the outgoing revision 4f1b60dd16 2007-11-22 aku: # changesets. Assuming that we have both incoming and outgoing 4f1b60dd16 2007-11-22 aku: # revision changesets. 4f1b60dd16 2007-11-22 aku: 4f1b60dd16 2007-11-22 aku: # The helper "Positions" computes the set of commit positions 4f1b60dd16 2007-11-22 aku: # for a set of changesets, which can be a mix of revision and 4f1b60dd16 2007-11-22 aku: # symbol changesets. 4f1b60dd16 2007-11-22 aku: 4f1b60dd16 2007-11-22 aku: set predecessors [Positions [$dg nodes -in $cset]] 4f1b60dd16 2007-11-22 aku: set successors [Positions [$dg nodes -out $cset]] 4f1b60dd16 2007-11-22 aku: 4f1b60dd16 2007-11-22 aku: return [expr { 4f1b60dd16 2007-11-22 aku: [llength $predecessors] && 4f1b60dd16 2007-11-22 aku: [llength $successors] && 4f1b60dd16 2007-11-22 aku: ([max $predecessors] >= [min $successors]) 4f1b60dd16 2007-11-22 aku: }] 4f1b60dd16 2007-11-22 aku: } 4f1b60dd16 2007-11-22 aku: 4f1b60dd16 2007-11-22 aku: proc Positions {changesets} { 4f1b60dd16 2007-11-22 aku: # To compute the set of commit positions from the set of 4f1b60dd16 2007-11-22 aku: # changesets we first map each changeset to its position (*) 4f1b60dd16 2007-11-22 aku: # and then filter out the invalid responses (the empty string) 4f1b60dd16 2007-11-22 aku: # returned by the symbol changesets. 4f1b60dd16 2007-11-22 aku: # 4f1b60dd16 2007-11-22 aku: # (*) This data was loaded into memory earlir in the pass, by 4f1b60dd16 2007-11-22 aku: # LoadCommitOrder. 4f1b60dd16 2007-11-22 aku: 4f1b60dd16 2007-11-22 aku: return [struct::list filter [struct::list map $changesets \ 4f1b60dd16 2007-11-22 aku: [myproc ToPosition]] \ 4f1b60dd16 2007-11-22 aku: [myproc ValidPosition]] 1f60018119 2007-11-21 aku: } 4f1b60dd16 2007-11-22 aku: 4f1b60dd16 2007-11-22 aku: proc ToPosition {cset} { $cset pos } 4f1b60dd16 2007-11-22 aku: proc ValidPosition {pos} { expr {$pos ne ""} } 1f60018119 2007-11-21 aku: 1f60018119 2007-11-21 aku: # # ## ### ##### ######## ############# 1f60018119 2007-11-21 aku: 1f60018119 2007-11-21 aku: proc SaveOrder {cset pos} { 1f60018119 2007-11-21 aku: } 1f60018119 2007-11-21 aku: 1f60018119 2007-11-21 aku: # # ## ### ##### ######## ############# 1f60018119 2007-11-21 aku: 1f60018119 2007-11-21 aku: proc BreakCycle {graph} { 1f60018119 2007-11-21 aku: cyclebreaker break $graph 1f60018119 2007-11-21 aku: } de4cff4142 2007-11-22 aku: de4cff4142 2007-11-22 aku: # # ## ### ##### ######## ############# de4cff4142 2007-11-22 aku: de4cff4142 2007-11-22 aku: typevariable mycset -array {} ; # Map from commit positions to the de4cff4142 2007-11-22 aku: # changeset (object ref) at that de4cff4142 2007-11-22 aku: # position. 1f60018119 2007-11-21 aku: e7c805f137 2007-11-16 aku: # # ## ### ##### ######## ############# e7c805f137 2007-11-16 aku: ## Configuration e7c805f137 2007-11-16 aku: e7c805f137 2007-11-16 aku: pragma -hasinstances no ; # singleton e7c805f137 2007-11-16 aku: pragma -hastypeinfo no ; # no introspection e7c805f137 2007-11-16 aku: pragma -hastypedestroy no ; # immortal e7c805f137 2007-11-16 aku: e7c805f137 2007-11-16 aku: # # ## ### ##### ######## ############# e7c805f137 2007-11-16 aku: } e7c805f137 2007-11-16 aku: e7c805f137 2007-11-16 aku: namespace eval ::vc::fossil::import::cvs::pass { e7c805f137 2007-11-16 aku: namespace export breakacycle e7c805f137 2007-11-16 aku: namespace eval breakacycle { e7c805f137 2007-11-16 aku: namespace import ::vc::fossil::import::cvs::cyclebreaker 1f60018119 2007-11-21 aku: namespace import ::vc::fossil::import::cvs::repository e7c805f137 2007-11-16 aku: namespace import ::vc::fossil::import::cvs::state e7c805f137 2007-11-16 aku: namespace eval project { e7c805f137 2007-11-16 aku: namespace import ::vc::fossil::import::cvs::project::rev e7c805f137 2007-11-16 aku: } 4866889e88 2007-11-22 aku: namespace import ::vc::tools::misc::* 4866889e88 2007-11-22 aku: namespace import ::vc::tools::trouble e7c805f137 2007-11-16 aku: namespace import ::vc::tools::log e7c805f137 2007-11-16 aku: log register breakacycle e7c805f137 2007-11-16 aku: } e7c805f137 2007-11-16 aku: } e7c805f137 2007-11-16 aku: e7c805f137 2007-11-16 aku: # # ## ### ##### ######## ############# ##################### e7c805f137 2007-11-16 aku: ## Ready e7c805f137 2007-11-16 aku: e7c805f137 2007-11-16 aku: package provide vc::fossil::import::cvs::pass::breakacycle 1.0 e7c805f137 2007-11-16 aku: return