Overview
SHA1 Hash: | 6f8667b03e3a644953d6bd72e7eed9ba83881b08 |
---|---|
Date: | 2007-10-31 03:44:01 |
User: | aku |
Comment: | Added code creating aggregate symbol statistics. This completes pass 2 (CollRev). |
Timelines: | ancestors | descendants | both | trunk |
Other Links: | files | ZIP archive | manifest |
Tags And Properties
- branch=trunk inherited from [a28c83647d]
- sym-trunk inherited from [a28c83647d]
Changes
[hide diffs]Modified tools/cvs2fossil/lib/c2f_file.tcl from [bd5c5d46d2] to [a0a48d681e].
@@ -232,11 +232,12 @@ } method done {} { # Complete the revisions, branches, and tags. This includes # looking for a non-trunk default branch, marking its members - # and linking them into the trunk. + # and linking them into the trunk, possibly excluding + # non-trunk data, and collecting aggregate symbol statistics. $self DetermineRevisionOperations $self DetermineLinesOfDevelopment $self HandleNonTrunkDefaultBranch $self RemoveIrrelevantDeletions @@ -243,10 +244,12 @@ $self RemoveInitialBranchDeletions if {[$myproject trunkonly]} { $self ExcludeNonTrunkInformation } + + $self AggregateSymbolData return } # # ## ### ##### ######## ############# ## State @@ -1022,10 +1025,64 @@ set root [$root child] } } return [list [lsort -unique -dict $revisions] [lsort -unique -dict $symbols]] + } + + + method AggregateSymbolData {} { + # Now that the exact set of revisions (and through that + # branches and tags) is known we can update the aggregate + # symbol statistics. + + foreach root [$self LinesOfDevelopment] { + set lod [$root lod] + + # Note: If the LOD is the trunk the count*, etc. methods + # will do nothing, as it is always present (cannot be + # excluded), and is always a branch too. + + # Lines of development count as branches and have a commit + # on them (root). If they are still attached to a tree we + # have to compute and register possible parents. + + $lod countasbranch + $lod countacommit + + if {[$root hasparentbranch]} { + # Note lod == [$root parentbranch] + $lod possibleparents + } + + # For the revisions in the line we register their branches + # and tags as blockers for the lod, and update the type + # counters as well. As branch symbols without commits on + # them are not listed as lines of development, we have to + # count them here as well, as plain branches. At last we + # have to compute and register the possible parents of the + # tags, in case they are later converted as branches. + + while {$root ne ""} { + foreach branch [$root branches] { + $lod blockedby $branch + $branch possibleparents + if {[$branch haschild]} continue + $branch countasbranch + } + + foreach tag [$root tags] { + $lod blockedby $tag + $tag possibleparents + $tag countastag + } + + set root [$root child] + } + } + + return } # # ## ### ##### ######## ############# ## Configuration
Modified tools/cvs2fossil/lib/c2f_fsym.tcl from [ce3e976f91] to [605873f19e].
@@ -45,16 +45,72 @@ method defid {} { set myid [incr myidcounter] return } - method fid {} { return $myid } + method fid {} { return $myid } + method symbol {} { return $mysymbol } # Symbol acessor methods. delegate method name to mysymbol delegate method id to mysymbol + + # Symbol aggregation methods + + delegate method countasbranch to mysymbol + delegate method countastag to mysymbol + delegate method countacommit to mysymbol + + method blockedby {fsymbol} { + $mysymbol blockedby [$fsymbol symbol] + return + } + + method possibleparents {} { + switch -exact -- $mytype { + branch { $self BranchParents } + tag { $self TagParents } + } + return + } + + method BranchParents {} { + # The "obvious" parent of a branch is the branch holding the + # revision spawning the branch. Any other branches that are + # rooted at the same revision and were committed earlier than + # the branch are also possible parents. + + $mysymbol possibleparent [[$mybranchparent lod] symbol] + + foreach branch [$mybranchparent branches] { + # A branch cannot be its own parent. Nor can a branch + # created after this one be its parent. This means that we + # can abort the loop when we have reached ourselves in the + # list of branches. Here the order of file::rev.mybranches + # comes into play, as created by file::rev::sortbranches. + + if {$branch eq $self} break + $mysymbol possibleparent [$branch symbol] + } + return + } + + method TagParents {} { + # The "obvious" parent of a tag is the branch holding the + # revision spawning the tag. Branches that are spawned by the + # same revision are also possible parents. + + $mysymbol possibleparent [[$mytagrev lod] symbol] + + foreach branch [$mytagrev branches] { + $mysymbol possibleparent [$branch symbol] + } + return + } + + # method istrunk {} { return 0 } # Branch acessor methods. @@ -75,11 +131,10 @@ method haschildrev {} { return [expr {$mybranchchildrevnr ne ""}] } method haschild {} { return [expr {$mybranchchild ne ""}] } method parent {} { return $mybranchparent } method child {} { return $mybranchchild } method position {} { return $mybranchposition } - # Tag acessor methods. method tagrevnr {} { return $mynr } method settagrev {rev} {set mytagrev $rev ; return }
Modified tools/cvs2fossil/lib/c2f_pcollrev.tcl from [46bf84e9d5] to [e14d8add6b].
@@ -186,18 +186,25 @@ UNIQUE (pid, name) -- Symbols are unique within the project } state writing blocker { + -- For each symbol we save which other symbols are + -- blocking its removal (if the user asks for it). + sid INTEGER NOT NULL REFERENCES symbol, -- bid INTEGER NOT NULL REFERENCES symbol, -- Sprouted from sid, blocks it. UNIQUE (sid, bid) } state writing parent { + -- For each symbol we save which other symbols can act as + -- a possible parent in some file, and how often. + sid INTEGER NOT NULL REFERENCES symbol, -- pid INTEGER NOT NULL REFERENCES symbol, -- Possible parent of sid + n INTEGER NOT NULL, -- How often pid can act as parent. UNIQUE (sid, pid) } state writing meta { -- Meta data of revisions. See revision.mid for the @@ -283,10 +290,12 @@ $file persist } $file drop } + + $project purgeghostsymbols } repository printrevstatistics repository persistrev @@ -312,11 +321,11 @@ return } proc Paranoia {} { # This code performs a number of paranoid checks of the - # database for inconsistent cross-references. + # database, searching for inconsistent cross-references. log write 4 collrev {Check database consistency} set n 0 ; # Counter for the checks (we print an id before the # main label).
Modified tools/cvs2fossil/lib/c2f_project.tcl from [00f1aee876] to [95678098d7].
@@ -19,10 +19,11 @@ package require snit ; # OO system. package require vc::fossil::import::cvs::file ; # CVS archive file. package require vc::fossil::import::cvs::state ; # State storage. package require vc::fossil::import::cvs::project::sym ; # Per project symbols. package require vc::fossil::import::cvs::project::trunk ; # Per project trunk, main lod +package require vc::tools::log ; # User feedback package require struct::list ; # Advanced list operations.. # # ## ### ##### ######## ############# ##################### ## @@ -32,10 +33,11 @@ constructor {path r} { set mybase $path set myrepository $r set mytrunk [trunk %AUTO% $self] + set mysymbol([$mytrunk name]) $mytrunk return } method base {} { return $mybase } method trunk {} { return $mytrunk } @@ -74,10 +76,25 @@ if {![info exists mysymbol($name)]} { set mysymbol($name) \ [sym %AUTO% $name [$myrepository defsymbol $myid $name] $self] } return $mysymbol($name) + } + + method purgeghostsymbols {} { + set changes 1 + while {$changes} { + set changes 0 + foreach {name symbol} [array get mysymbol] { + if {![$symbol isghost]} continue + log write 3 project "$mybase: Deleting ghost symbol '$name'" + $symbol destroy + unset mysymbol($name) + set changes 1 + } + } + return } # pass I persistence method persist {} { TheFiles ; # Force id assignment. @@ -177,10 +194,11 @@ } namespace eval ::vc::fossil::import::cvs { namespace export project namespace eval project { + namespace import ::vc::tools::log namespace import ::vc::fossil::import::cvs::file namespace import ::vc::fossil::import::cvs::state # Import not required, already a child namespace. # namespace import ::vc::fossil::import::cvs::project::sym }
Modified tools/cvs2fossil/lib/c2f_psym.tcl from [6432e54926] to [ec9334ebb7].
@@ -15,10 +15,11 @@ # # ## ### ##### ######## ############# ##################### ## Requirements package require Tcl 8.4 ; # Required runtime. package require snit ; # OO system. +package require struct::set ; # Set handling. package require vc::fossil::import::cvs::state ; # State storage. # # ## ### ##### ######## ############# ##################### ## @@ -35,22 +36,68 @@ method name {} { return $myname } method id {} { return $myid } # # ## ### ##### ######## ############# + ## Symbol statistics + + method countasbranch {} { incr mybranchcount ; return } + method countastag {} { incr mytagcount ; return } + method countacommit {} { incr mycommitcount ; return } + + method blockedby {symbol} { + # Remember the symbol as preventing the removal of this + # symbol. Ot is a tag or branch that spawned from a revision + # on this symbol. + + struct::set include myblockers $symbol + return + } + + method possibleparent {symbol} { + if {[info exists mypparent($symbol)]} { + incr mypparent($symbol) + } else { + set mypparent($symbol) 1 + } + return + } + + method isghost {} { + # Checks if this symbol (as line of development) never + # existed. + + if {$mycommitcount > 0} { return 0 } + if {[llength $myblockers]} { return 0 } + if {[array size mypparent] > 0} { return 0 } + + return 1 + } + + # # ## ### ##### ######## ############# method persistrev {} { set pid [$myproject id] - # TODO: Compute the various counts. All the necessary - # TODO: information is already in the database. Actually it - # TODO: never was in memory. - state transaction { state run { - INSERT INTO symbol ( sid, pid, name, type, tag_count, branch_count, commit_count) - VALUES ($myid, $pid, $myname, $myundef, 0, 0, 0); + INSERT INTO symbol ( sid, pid, name, type, tag_count, branch_count, commit_count) + VALUES ($myid, $pid, $myname, $myundef, $mytagcount, $mybranchcount, $mycommitcount); + } + foreach symbol $myblockers { + set bid [$symbol id] + state run { + INSERT INTO blocker (sid, bid) + VALUES ($myid, $bid); + } + } + foreach {symbol count} [array get mypparent] { + set pid [$symbol id] + state run { + INSERT INTO parent (sid, pid, n) + VALUES ($myid, $pid, $count); + } } } return } @@ -61,10 +108,21 @@ # containing the symbol. variable myname {} ; # The symbol's name variable myid {} ; # Repository wide numeric id of the # symbol. This implicitly encodes the # project as well. + + variable mybranchcount 0 ; # Count how many uses as branch. + variable mytagcount 0 ; # Count how many uses as tag. + variable mycommitcount 0 ; # Count how many files did a commit on the symbol. + + variable myblockers {} ; # List (Set) of the symbols which block + # the exclusion of this symbol. + + variable mypparent -array {} ; # Maps from symbols to the number + # of files in which it could have + # been a parent of this symbol. typevariable mytag 1 ; # Code for symbols which are tags. typevariable mybranch 2 ; # Code for symbols which are branches. typevariable myundef 3 ; # Code for symbols of unknown type.
Modified tools/cvs2fossil/lib/c2f_ptrunk.tcl from [186b2dcb0d] to [7dec41a873].
@@ -24,23 +24,41 @@ snit::type ::vc::fossil::import::cvs::project::trunk { # # ## ### ##### ######## ############# ## Public API constructor {project} { - set myid [[$project getsymbol $myname] id] + set mysymbol [$project getsymbol $myname] + set myid [$mysymbol id] return + } + + destructor { + $mysymbol destroy } method name {} { return $myname } method id {} { return $myid } method istrunk {} { return 1 } + method symbol {} { return $self } + + method countasbranch {} {} + method countastag {} {} + method countacommit {} {} + + method blockedby {symbol} {} + method possibleparent {symbol} {} + + method isghost {} { return 0 } + + delegate method persistrev to mysymbol # # ## ### ##### ######## ############# ## State - typevariable myname :trunk: ; # Name shared by all trunk symbols. - variable myid {} ; # The trunk's symbol id. + typevariable myname :trunk: ; # Name shared by all trunk symbols. + variable myid {} ; # The trunk's symbol id. + variable mysymbol {} ; # The symbol underneath the trunk. # # ## ### ##### ######## ############# ## Internal methods # # ## ### ##### ######## ############# @@ -47,11 +65,10 @@ ## Configuration pragma -hastypeinfo no ; # no type introspection pragma -hasinfo no ; # no object introspection pragma -hastypemethods no ; # type is not relevant. - pragma -simpledispatch yes ; # simple fast dispatch # # ## ### ##### ######## ############# } namespace eval ::vc::fossil::import::cvs::project {