Differences From:
File tools/cvs2fossil/lib/c2f_prev.tcl part of check-in [00bf8c198e] - The performance was still not satisfying, even with faster recomputing of successors. Doing it multiple times (Building the graph in each breaker and sort passes) eats time. Caching in memory blows the memory. Chosen solution: Cache this information in the database.Created a new pass 'CsetDeps' which is run between 'InitCsets' and 'BreakRevCsetCycles' (i.e. changeset creation and first breaker pass). It computes the changeset dependencies from the file-level dependencies once and saves the result in the state, in the new table 'cssuccessor'. Now the breaker and sort passes can get the information quickly, with virtually no effort. The dependencies are recomputed incrementally when a changeset is split by one of the breaker passes, for its fragments and its predecessors.
The loop check is now trivial, and integrated into the successor computation, with the heavy lifting for the detailed analysis and reporting moved down into the type-dependent SQL queries. The relevant new method is 'loops'. Now that the loop check is incremental the pass based checks have been removed from the integrity module, and the option '--loopcheck' has been eliminated. For paranoia the graph setup and modification code got its loop check reinstated as an assert, redusing the changeset report code.
Renumbered the breaker and sort passes. A number of places, like graph setup and traversal, loading of changesets, etc. got feedback indicators to show their progress.
The selection of revision and symbol changesets for the associated breaker passes was a bit on the slow side. We now keep changeset lists sorted by type (during loading or general construction) and access them directly.
by aku on 2007-12-02 20:04:40. [view]
To:
File tools/cvs2fossil/lib/c2f_prev.tcl part of check-in [711e000206] - Reworked ComputeLimits in the last breaker pass. Moved the heavy computation of the max predecessor / min successor data down to the sql in the changeset class. by aku on 2007-12-04 04:54:10. [view]
@@ -380,8 +380,13 @@ } method timerange {} { return [$mytypeobj timerange $myitems] } + method limits {} { + struct::list assign [$mytypeobj limits $myitems] maxp mins + return [list [TagItemDict $maxp $mytype] [TagItemDict $mins $mytype]] + } + method drop {} { log write 8 csets {Dropping $self = [$self str]} state transaction { @@ -494,8 +499,14 @@ proc Untag1 {cstype theitem} { struct::list assign $theitem t i integrity assert {$cstype eq $t} {Item $i's type is '$t', expected '$cstype'} return $i + } + + proc TagItemDict {itemdict cstype} { + set res {} + foreach {i v} $itemdict { lappend res [list $cstype $i] $v } + return $res } proc ValidateFragments {cset fragments} { # Check the various integrity constraints for the fragments @@ -1461,8 +1472,47 @@ AND C.cid = CI.cid AND C.type = 1 "] return + } + + typemethod limits {branches} { + # Notes. This method exists only for branches. It is needed to + # get detailed information about a backward branch. It does + # not apply to tags, nor revisions. The queries can also + # restrict themselves to the revision sucessors/predecessors + # of branches, as only they have ordering data and thus can + # cause the backwardness. + + set theset ('[join $branches {','}]') + + set maxp [state run [subst -nocommands -nobackslashes { + -- maximal predecessor position per branch + SELECT B.bid, MAX (CO.pos) + FROM branch B, revision R, csitem CI, changeset C, csorder CO + WHERE B.bid IN $theset + AND B.root = R.rid + AND CI.iid = R.rid + AND C.cid = CI.cid + AND C.type = 0 + AND CO.cid = C.cid + GROUP BY B.bid + }]] + + set mins [state run [subst -nocommands -nobackslashes { + -- minimal successor position per branch + SELECT B.bid, MIN (CO.pos) + FROM branch B, revision R, csitem CI, changeset C, csorder CO + WHERE B.bid IN $theset + AND B.first = R.rid + AND CI.iid = R.rid + AND C.cid = CI.cid + AND C.type = 0 + AND CO.cid = C.cid + GROUP BY B.bid + }]] + + return [list $maxp $mins] } # # ## ### ##### ######## ############# ## Configuration