File Annotation
Not logged in
84de38d73f 2007-10-10       aku: ## -*- tcl -*-
84de38d73f 2007-10-10       aku: # # ## ### ##### ######## ############# #####################
84de38d73f 2007-10-10       aku: ## Copyright (c) 2007 Andreas Kupries.
84de38d73f 2007-10-10       aku: #
84de38d73f 2007-10-10       aku: # This software is licensed as described in the file LICENSE, which
84de38d73f 2007-10-10       aku: # you should have received as part of this distribution.
84de38d73f 2007-10-10       aku: #
84de38d73f 2007-10-10       aku: # This software consists of voluntary contributions made by many
84de38d73f 2007-10-10       aku: # individuals.  For exact contribution history, see the revision
84de38d73f 2007-10-10       aku: # history and logs, available at http://fossil-scm.hwaci.com/fossil
84de38d73f 2007-10-10       aku: # # ## ### ##### ######## ############# #####################
84de38d73f 2007-10-10       aku: 
5f7acef887 2007-11-10       aku: ## Revisions per project, aka Changesets. These objects are first used
5f7acef887 2007-11-10       aku: ## in pass 5, which creates the initial set covering the repository.
84de38d73f 2007-10-10       aku: 
84de38d73f 2007-10-10       aku: # # ## ### ##### ######## ############# #####################
84de38d73f 2007-10-10       aku: ## Requirements
84de38d73f 2007-10-10       aku: 
5f7acef887 2007-11-10       aku: package require Tcl 8.4                               ; # Required runtime.
5f7acef887 2007-11-10       aku: package require snit                                  ; # OO system.
08ebab80cd 2007-11-10       aku: package require vc::tools::misc                       ; # Text formatting
08ebab80cd 2007-11-10       aku: package require vc::tools::trouble                    ; # Error reporting.
95af789e1f 2007-11-10       aku: package require vc::tools::log                        ; # User feedback.
5f7acef887 2007-11-10       aku: package require vc::fossil::import::cvs::state        ; # State storage.
4866889e88 2007-11-22       aku: package require vc::fossil::import::cvs::project::sym ; # Project level symbols
84de38d73f 2007-10-10       aku: 
84de38d73f 2007-10-10       aku: # # ## ### ##### ######## ############# #####################
84de38d73f 2007-10-10       aku: ##
84de38d73f 2007-10-10       aku: 
84de38d73f 2007-10-10       aku: snit::type ::vc::fossil::import::cvs::project::rev {
84de38d73f 2007-10-10       aku:     # # ## ### ##### ######## #############
84de38d73f 2007-10-10       aku:     ## Public API
84de38d73f 2007-10-10       aku: 
65be27aa69 2007-11-22       aku:     constructor {project cstype srcid revisions {theid {}}} {
65be27aa69 2007-11-22       aku: 	if {$theid ne ""} {
65be27aa69 2007-11-22       aku: 	    set myid $theid
65be27aa69 2007-11-22       aku: 	} else {
65be27aa69 2007-11-22       aku: 	    set myid [incr mycounter]
65be27aa69 2007-11-22       aku: 	}
65be27aa69 2007-11-22       aku: 
5f7acef887 2007-11-10       aku: 	set myproject   $project
5f7acef887 2007-11-10       aku: 	set mytype      $cstype
5f7acef887 2007-11-10       aku: 	set mysrcid	$srcid
5f7acef887 2007-11-10       aku: 	set myrevisions $revisions
de4cff4142 2007-11-22       aku: 	set mypos       {} ; # Commit location is not known yet.
85bd219d0b 2007-11-13       aku: 
85bd219d0b 2007-11-13       aku: 	# Keep track of the generated changesets and of the inverse
85bd219d0b 2007-11-13       aku: 	# mapping from revisions to them.
de4cff4142 2007-11-22       aku: 	lappend mychangesets   $self
de4cff4142 2007-11-22       aku: 	set     myidmap($myid) $self
8c9030e3e8 2007-11-24       aku: 	foreach r $revisions { lappend myrevmap($r) $self }
5f7acef887 2007-11-10       aku: 	return
95af789e1f 2007-11-10       aku:     }
95af789e1f 2007-11-10       aku: 
0868adf92a 2007-11-25       aku:     method str {} { return "<$mytype ${myid}>" }
94c39d6375 2007-11-14       aku: 
85bd219d0b 2007-11-13       aku:     method id        {} { return $myid }
85bd219d0b 2007-11-13       aku:     method revisions {} { return $myrevisions }
94c39d6375 2007-11-14       aku:     method data      {} { return [list $myproject $mytype $mysrcid] }
85bd219d0b 2007-11-13       aku: 
85bd219d0b 2007-11-13       aku:     method bysymbol   {} { return [expr {$mytype eq "sym"}] }
85bd219d0b 2007-11-13       aku:     method byrevision {} { return [expr {$mytype eq "rev"}] }
85bd219d0b 2007-11-13       aku: 
de4cff4142 2007-11-22       aku:     method setpos {p} { set mypos $p ; return }
de4cff4142 2007-11-22       aku:     method pos    {}  { return $mypos }
de4cff4142 2007-11-22       aku: 
4866889e88 2007-11-22       aku:     method isbranch {} {
4866889e88 2007-11-22       aku: 	return [expr {($mytype eq "sym") &&
4866889e88 2007-11-22       aku: 		      ($mybranchcode == [state one {
4866889e88 2007-11-22       aku: 			  SELECT type FROM symbol WHERE sid = $mysrcid
4866889e88 2007-11-22       aku: 		      }])}]
4866889e88 2007-11-22       aku:     }
4866889e88 2007-11-22       aku: 
8c9030e3e8 2007-11-24       aku:     # result = dict (revision -> list (changeset))
e50f9ed55e 2007-11-22       aku:     method successormap {} {
e50f9ed55e 2007-11-22       aku: 	# NOTE / FUTURE: Possible bottleneck.
e50f9ed55e 2007-11-22       aku: 	array set tmp {}
e50f9ed55e 2007-11-22       aku: 	foreach {rev children} [$self nextmap] {
e50f9ed55e 2007-11-22       aku: 	    foreach child $children {
8c9030e3e8 2007-11-24       aku: 		# 8.5 lappend tmp($rev) {*}$myrevmap($child)
8c9030e3e8 2007-11-24       aku: 		foreach cset $myrevmap($child) {
8c9030e3e8 2007-11-24       aku: 		    lappend tmp($rev) $cset
8c9030e3e8 2007-11-24       aku: 		}
e50f9ed55e 2007-11-22       aku: 	    }
e50f9ed55e 2007-11-22       aku: 	    set tmp($rev) [lsort -unique $tmp($rev)]
e50f9ed55e 2007-11-22       aku: 	}
e50f9ed55e 2007-11-22       aku: 	return [array get tmp]
e50f9ed55e 2007-11-22       aku:     }
94c39d6375 2007-11-14       aku: 
85bd219d0b 2007-11-13       aku:     method successors {} {
85bd219d0b 2007-11-13       aku: 	# NOTE / FUTURE: Possible bottleneck.
85bd219d0b 2007-11-13       aku: 	set csets {}
94c39d6375 2007-11-14       aku: 	foreach {_ children} [$self nextmap] {
94c39d6375 2007-11-14       aku: 	    foreach child $children {
8c9030e3e8 2007-11-24       aku: 		# 8.5 lappend csets {*}$myrevmap($child)
8c9030e3e8 2007-11-24       aku: 		foreach cset $myrevmap($child) {
8c9030e3e8 2007-11-24       aku: 		    lappend csets $cset
8c9030e3e8 2007-11-24       aku: 		}
94c39d6375 2007-11-14       aku: 	    }
85bd219d0b 2007-11-13       aku: 	}
85bd219d0b 2007-11-13       aku: 	return [lsort -unique $csets]
94c39d6375 2007-11-14       aku:     }
94c39d6375 2007-11-14       aku: 
8c9030e3e8 2007-11-24       aku:     # result = dict (revision -> list (changeset))
e50f9ed55e 2007-11-22       aku:     method predecessormap {} {
e50f9ed55e 2007-11-22       aku: 	# NOTE / FUTURE: Possible bottleneck.
e50f9ed55e 2007-11-22       aku: 	array set tmp {}
e50f9ed55e 2007-11-22       aku: 	foreach {rev children} [$self premap] {
e50f9ed55e 2007-11-22       aku: 	    foreach child $children {
8c9030e3e8 2007-11-24       aku: 		# 8.5 lappend tmp($rev) {*}$myrevmap($child)
8c9030e3e8 2007-11-24       aku: 		foreach cset $myrevmap($child) {
8c9030e3e8 2007-11-24       aku: 		    lappend tmp($rev) $cset
8c9030e3e8 2007-11-24       aku: 		}
e50f9ed55e 2007-11-22       aku: 	    }
e50f9ed55e 2007-11-22       aku: 	    set tmp($rev) [lsort -unique $tmp($rev)]
e50f9ed55e 2007-11-22       aku: 	}
e50f9ed55e 2007-11-22       aku: 	return [array get tmp]
59207428e2 2007-11-22       aku:     }
59207428e2 2007-11-22       aku: 
59207428e2 2007-11-22       aku:     # revision -> list (revision)
94c39d6375 2007-11-14       aku:     method nextmap {} {
94c39d6375 2007-11-14       aku: 	if {[llength $mynextmap]} { return $mynextmap }
94c39d6375 2007-11-14       aku: 	PullSuccessorRevisions tmp $myrevisions
94c39d6375 2007-11-14       aku: 	set mynextmap [array get tmp]
94c39d6375 2007-11-14       aku: 	return $mynextmap
e50f9ed55e 2007-11-22       aku:     }
e50f9ed55e 2007-11-22       aku: 
e50f9ed55e 2007-11-22       aku:     # revision -> list (revision)
e50f9ed55e 2007-11-22       aku:     method premap {} {
e50f9ed55e 2007-11-22       aku: 	if {[llength $mypremap]} { return $mypremap }
e50f9ed55e 2007-11-22       aku: 	PullPredecessorRevisions tmp $myrevisions
e50f9ed55e 2007-11-22       aku: 	set mypremap [array get tmp]
e50f9ed55e 2007-11-22       aku: 	return $mypremap
85bd219d0b 2007-11-13       aku:     }
24c0b662de 2007-11-13       aku: 
24c0b662de 2007-11-13       aku:     method breakinternaldependencies {} {
95af789e1f 2007-11-10       aku: 	# This method inspects the changesets for internal
95af789e1f 2007-11-10       aku: 	# dependencies. Nothing is done if there are no
95af789e1f 2007-11-10       aku: 	# such. Otherwise the changeset is split into a set of
95af789e1f 2007-11-10       aku: 	# fragments without internal dependencies, transforming the
95af789e1f 2007-11-10       aku: 	# internal dependencies into external ones. The new changesets
95af789e1f 2007-11-10       aku: 	# are added to the list of all changesets.
95af789e1f 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	# We perform all necessary splits in one go, instead of only
08ebab80cd 2007-11-10       aku: 	# one. The previous algorithm, adapted from cvs2svn, computed
08ebab80cd 2007-11-10       aku: 	# a lot of state which was thrown away and then computed again
08ebab80cd 2007-11-10       aku: 	# for each of the fragments. It should be easier to update and
08ebab80cd 2007-11-10       aku: 	# reuse that state.
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	# The code checks only sucessor dependencies, as this
08ebab80cd 2007-11-10       aku: 	# automatically covers the predecessor dependencies as well (A
08ebab80cd 2007-11-10       aku: 	# successor dependency a -> b is also a predecessor dependency
08ebab80cd 2007-11-10       aku: 	# b -> a).
95af789e1f 2007-11-10       aku: 
95af789e1f 2007-11-10       aku: 	# Array of dependencies (parent -> child). This is pulled from
95af789e1f 2007-11-10       aku: 	# the state, and limited to successors within the changeset.
08ebab80cd 2007-11-10       aku: 
95af789e1f 2007-11-10       aku: 	array set dependencies {}
94c39d6375 2007-11-14       aku: 	PullInternalSuccessorRevisions dependencies $myrevisions
95af789e1f 2007-11-10       aku: 	if {![array size dependencies]} {return 0} ; # Nothing to break.
08ebab80cd 2007-11-10       aku: 
87cf609021 2007-11-24       aku: 	log write 6 csets ...[$self str].......................................................
95af789e1f 2007-11-10       aku: 
95af789e1f 2007-11-10       aku: 	# We have internal dependencies to break. We now iterate over
95af789e1f 2007-11-10       aku: 	# all positions in the list (which is chronological, at least
95af789e1f 2007-11-10       aku: 	# as far as the timestamps are correct and unique) and
95af789e1f 2007-11-10       aku: 	# determine the best position for the break, by trying to
08ebab80cd 2007-11-10       aku: 	# break as many dependencies as possible in one go. When a
08ebab80cd 2007-11-10       aku: 	# break was found this is redone for the fragments coming and
08ebab80cd 2007-11-10       aku: 	# after, after upding the crossing information.
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	# Data structures:
08ebab80cd 2007-11-10       aku: 	# Map:  POS   revision id      -> position in list.
08ebab80cd 2007-11-10       aku: 	#       CROSS position in list -> number of dependencies crossing it
08ebab80cd 2007-11-10       aku: 	#       DEPC  dependency       -> positions it crosses
08ebab80cd 2007-11-10       aku: 	# List: RANGE Of the positions itself.
08ebab80cd 2007-11-10       aku: 	# A dependency is a single-element map parent -> child
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	InitializeBreakState $myrevisions
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	set fragments {}
08ebab80cd 2007-11-10       aku: 	set pending   [list $range]
08ebab80cd 2007-11-10       aku: 	set at        0
08ebab80cd 2007-11-10       aku: 	array set breaks {}
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	while {$at < [llength $pending]} {
08ebab80cd 2007-11-10       aku: 	    set current [lindex $pending $at]
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	    log write 6 csets ". . .. ... ..... ........ ............."
08ebab80cd 2007-11-10       aku: 	    log write 6 csets "Scheduled   [join [PRs [lrange $pending $at end]] { }]"
08ebab80cd 2007-11-10       aku: 	    log write 6 csets "Considering [PR $current] \[$at/[llength $pending]\]"
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	    set best [FindBestBreak $current]
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	    if {$best < 0} {
08ebab80cd 2007-11-10       aku: 		# The inspected range has no internal
08ebab80cd 2007-11-10       aku: 		# dependencies. This is a complete fragment.
08ebab80cd 2007-11-10       aku: 		lappend fragments $current
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 		log write 6 csets "No breaks, final"
95af789e1f 2007-11-10       aku: 	    } else {
08ebab80cd 2007-11-10       aku: 		# Split the range and schedule the resulting fragments
08ebab80cd 2007-11-10       aku: 		# for further inspection. Remember the number of
08ebab80cd 2007-11-10       aku: 		# dependencies cut before we remove them from
08ebab80cd 2007-11-10       aku: 		# consideration, for documentation later.
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 		set breaks($best) $cross($best)
08ebab80cd 2007-11-10       aku: 
96b7bfb834 2007-11-16       aku: 		log write 6 csets "Best break @ $best, cutting [nsp $cross($best) dependency dependencies]"
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 		# Note: The value of best is an abolute location in
08ebab80cd 2007-11-10       aku: 		# myrevisions. Use the start of current to make it an
08ebab80cd 2007-11-10       aku: 		# index absolute to current.
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 		set brel [expr {$best - [lindex $current 0]}]
08ebab80cd 2007-11-10       aku: 		set bnext $brel ; incr bnext
08ebab80cd 2007-11-10       aku: 		set fragbefore [lrange $current 0 $brel]
08ebab80cd 2007-11-10       aku: 		set fragafter  [lrange $current $bnext end]
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 		log write 6 csets "New pieces  [PR $fragbefore] [PR $fragafter]"
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 		if {![llength $fragbefore]} {
08ebab80cd 2007-11-10       aku: 		    trouble internal "Tried to split off a zero-length fragment at the beginning"
08ebab80cd 2007-11-10       aku: 		}
08ebab80cd 2007-11-10       aku: 		if {![llength $fragafter]} {
08ebab80cd 2007-11-10       aku: 		    trouble internal "Tried to split off a zero-length fragment at the end"
95af789e1f 2007-11-10       aku: 		}
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 		lappend pending $fragbefore $fragafter
08ebab80cd 2007-11-10       aku: 		CutAt $best
08ebab80cd 2007-11-10       aku: 	    }
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	    incr at
08ebab80cd 2007-11-10       aku: 	}
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	log write 6 csets ". . .. ... ..... ........ ............."
08ebab80cd 2007-11-10       aku: 
17ec2d682c 2007-11-24       aku: 	# (*) We clear out the associated part of the myrevmap
17ec2d682c 2007-11-24       aku: 	# in-memory index in preparation for new data. A simple unset
17ec2d682c 2007-11-24       aku: 	# is enough, we have no symbol changesets at this time, and
17ec2d682c 2007-11-24       aku: 	# thus never more than one reference in the list.
17ec2d682c 2007-11-24       aku: 
17ec2d682c 2007-11-24       aku: 	foreach r $myrevisions { unset myrevmap($r) }
17ec2d682c 2007-11-24       aku: 
08ebab80cd 2007-11-10       aku: 	# Create changesets for the fragments, reusing the current one
08ebab80cd 2007-11-10       aku: 	# for the first fragment. We sort them in order to allow
08ebab80cd 2007-11-10       aku: 	# checking for gaps and nice messages.
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	set fragments [lsort -index 0 -integer $fragments]
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	#puts \t.[join [PRs $fragments] .\n\t.].
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	Border [lindex $fragments 0] firsts firste
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	if {$firsts != 0} {
08ebab80cd 2007-11-10       aku: 	    trouble internal "Bad fragment start @ $firsts, gap, or before beginning of the range"
08ebab80cd 2007-11-10       aku: 	}
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	set laste $firste
08ebab80cd 2007-11-10       aku: 	foreach fragment [lrange $fragments 1 end] {
08ebab80cd 2007-11-10       aku: 	    Border $fragment s e
08ebab80cd 2007-11-10       aku: 	    if {$laste != ($s - 1)} {
08ebab80cd 2007-11-10       aku: 		trouble internal "Bad fragment border <$laste | $s>, gap or overlap"
95af789e1f 2007-11-10       aku: 	    }
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	    set new [$type %AUTO% $myproject $mytype $mysrcid [lrange $myrevisions $s $e]]
24c0b662de 2007-11-13       aku: 
87cf609021 2007-11-24       aku:             log write 4 csets "Breaking [$self str ] @ $laste, new [$new str], cutting $breaks($laste)"
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	    set laste $e
08ebab80cd 2007-11-10       aku: 	}
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	if {$laste != ([llength $myrevisions]-1)} {
08ebab80cd 2007-11-10       aku: 	    trouble internal "Bad fragment end @ $laste, gap, or beyond end of the range"
08ebab80cd 2007-11-10       aku: 	}
08ebab80cd 2007-11-10       aku: 
17ec2d682c 2007-11-24       aku: 	# Put the first fragment into the current changeset, and
17ec2d682c 2007-11-24       aku: 	# update the in-memory index. We can simply (re)add the
17ec2d682c 2007-11-24       aku: 	# revisions because we cleared the previously existing
17ec2d682c 2007-11-24       aku: 	# information, see (*) above. Persistence does not matter
17ec2d682c 2007-11-24       aku: 	# here, none of the changesets has been saved to the
17ec2d682c 2007-11-24       aku: 	# persistent state yet.
17ec2d682c 2007-11-24       aku: 
08ebab80cd 2007-11-10       aku: 	set myrevisions [lrange $myrevisions 0 $firste]
17ec2d682c 2007-11-24       aku: 	foreach r $myrevisions { lappend myrevmap($r) $self }
95af789e1f 2007-11-10       aku: 
95af789e1f 2007-11-10       aku: 	return 1
5f7acef887 2007-11-10       aku:     }
5f7acef887 2007-11-10       aku: 
5f7acef887 2007-11-10       aku:     method persist {} {
5f7acef887 2007-11-10       aku: 	set tid $mycstype($mytype)
5f7acef887 2007-11-10       aku: 	set pid [$myproject id]
5f7acef887 2007-11-10       aku: 	set pos 0
5f7acef887 2007-11-10       aku: 
5f7acef887 2007-11-10       aku: 	state transaction {
5f7acef887 2007-11-10       aku: 	    state run {
5f7acef887 2007-11-10       aku: 		INSERT INTO changeset (cid,   pid,  type, src)
5f7acef887 2007-11-10       aku: 		VALUES                ($myid, $pid, $tid, $mysrcid);
5f7acef887 2007-11-10       aku: 	    }
5f7acef887 2007-11-10       aku: 
5f7acef887 2007-11-10       aku: 	    foreach rid $myrevisions {
5f7acef887 2007-11-10       aku: 		state run {
5f7acef887 2007-11-10       aku: 		    INSERT INTO csrevision (cid,   pos,  rid)
5f7acef887 2007-11-10       aku: 		    VALUES                 ($myid, $pos, $rid);
5f7acef887 2007-11-10       aku: 		}
5f7acef887 2007-11-10       aku: 		incr pos
5f7acef887 2007-11-10       aku: 	    }
5f7acef887 2007-11-10       aku: 	}
5f7acef887 2007-11-10       aku: 	return
5f7acef887 2007-11-10       aku:     }
5f7acef887 2007-11-10       aku: 
85bd219d0b 2007-11-13       aku:     method timerange {} {
85bd219d0b 2007-11-13       aku: 	set theset ('[join $myrevisions {','}]')
85bd219d0b 2007-11-13       aku: 	return [state run "
85bd219d0b 2007-11-13       aku: 	    SELECT MIN(R.date), MAX(R.date)
85bd219d0b 2007-11-13       aku: 	    FROM revision R
85bd219d0b 2007-11-13       aku: 	    WHERE R.rid IN $theset
85bd219d0b 2007-11-13       aku: 	"]
85bd219d0b 2007-11-13       aku:     }
85bd219d0b 2007-11-13       aku: 
94c39d6375 2007-11-14       aku:     method drop {} {
94c39d6375 2007-11-14       aku: 	state transaction {
94c39d6375 2007-11-14       aku: 	    state run {
94c39d6375 2007-11-14       aku: 		DELETE FROM changeset  WHERE cid = $myid;
94c39d6375 2007-11-14       aku: 		DELETE FROM csrevision WHERE cid = $myid;
94c39d6375 2007-11-14       aku: 	    }
94c39d6375 2007-11-14       aku: 	}
8c9030e3e8 2007-11-24       aku: 	foreach r $myrevisions {
8c9030e3e8 2007-11-24       aku: 	    if {[llength $myrevmap($r)] == 1} {
8c9030e3e8 2007-11-24       aku: 		unset myrevmap($r)
8c9030e3e8 2007-11-24       aku: 	    } else {
8c9030e3e8 2007-11-24       aku: 		set pos [lsearch -exact $myrevmap($r) $self]
8c9030e3e8 2007-11-24       aku: 		set myrevmap($r) [lreplace $myrevmap($r) $pos $pos]
8c9030e3e8 2007-11-24       aku: 	    }
8c9030e3e8 2007-11-24       aku: 	}
94c39d6375 2007-11-14       aku: 	set pos          [lsearch -exact $mychangesets $self]
94c39d6375 2007-11-14       aku: 	set mychangesets [lreplace $mychangesets $pos $pos]
84de38d73f 2007-10-10       aku: 	return
84de38d73f 2007-10-10       aku:     }
59207428e2 2007-11-22       aku: 
59207428e2 2007-11-22       aku:     typemethod split {cset args} {
59207428e2 2007-11-22       aku: 	# As part of the creation of the new changesets specified in
59207428e2 2007-11-22       aku: 	# ARGS as sets of revisions, all subsets of CSET's revision
59207428e2 2007-11-22       aku: 	# set, CSET will be dropped from all databases, in and out of
59207428e2 2007-11-22       aku: 	# memory, and then destroyed.
59207428e2 2007-11-22       aku: 
59207428e2 2007-11-22       aku: 	struct::list assign [$cset data] project cstype cssrc
59207428e2 2007-11-22       aku: 
59207428e2 2007-11-22       aku: 	$cset drop
59207428e2 2007-11-22       aku: 	$cset destroy
59207428e2 2007-11-22       aku: 
59207428e2 2007-11-22       aku: 	set newcsets {}
59207428e2 2007-11-22       aku: 	foreach fragmentrevisions $args {
eabaea870a 2007-11-24       aku: 	    if {![llength $fragmentrevisions]} {
eabaea870a 2007-11-24       aku: 		trouble internal "Attempted to create an empty changeset, i.e. without revisions"
eabaea870a 2007-11-24       aku: 	    }
59207428e2 2007-11-22       aku: 	    lappend newcsets [$type %AUTO% $project $cstype $cssrc $fragmentrevisions]
59207428e2 2007-11-22       aku: 	}
59207428e2 2007-11-22       aku: 
59207428e2 2007-11-22       aku: 	foreach c $newcsets { $c persist }
59207428e2 2007-11-22       aku: 	return $newcsets
59207428e2 2007-11-22       aku:     }
17ec2d682c 2007-11-24       aku: 
87cf609021 2007-11-24       aku:     typemethod strlist {changesets} {
87cf609021 2007-11-24       aku: 	return [join [struct::list map $changesets [myproc ID]]]
87cf609021 2007-11-24       aku:     }
87cf609021 2007-11-24       aku: 
87cf609021 2007-11-24       aku:     proc ID {cset} { $cset str }
84de38d73f 2007-10-10       aku: 
84de38d73f 2007-10-10       aku:     # # ## ### ##### ######## #############
84de38d73f 2007-10-10       aku:     ## State
84de38d73f 2007-10-10       aku: 
94c39d6375 2007-11-14       aku:     variable myid        {} ; # Id of the cset for the persistent
94c39d6375 2007-11-14       aku: 			      # state.
94c39d6375 2007-11-14       aku:     variable myproject   {} ; # Reference of the project object the
94c39d6375 2007-11-14       aku: 			      # changeset belongs to.
94c39d6375 2007-11-14       aku:     variable mytype      {} ; # rev or sym, where the cset originated
94c39d6375 2007-11-14       aku: 			      # from.
94c39d6375 2007-11-14       aku:     variable mysrcid     {} ; # Id of the metadata or symbol the cset
94c39d6375 2007-11-14       aku: 			      # is based on.
94c39d6375 2007-11-14       aku:     variable myrevisions {} ; # List of the file level revisions in
94c39d6375 2007-11-14       aku: 			      # the cset.
e50f9ed55e 2007-11-22       aku:     variable mypremap    {} ; # Dictionary mapping from the revisions
e50f9ed55e 2007-11-22       aku: 			      # to their predecessors. Cache to avoid
e50f9ed55e 2007-11-22       aku: 			      # loading this from the state more than
e50f9ed55e 2007-11-22       aku: 			      # once.
94c39d6375 2007-11-14       aku:     variable mynextmap   {} ; # Dictionary mapping from the revisions
94c39d6375 2007-11-14       aku: 			      # to their successors. Cache to avoid
94c39d6375 2007-11-14       aku: 			      # loading this from the state more than
94c39d6375 2007-11-14       aku: 			      # once.
de4cff4142 2007-11-22       aku:     variable mypos       {} ; # Commit position of the changeset, if
de4cff4142 2007-11-22       aku: 			      # known.
5f7acef887 2007-11-10       aku: 
84de38d73f 2007-10-10       aku:     # # ## ### ##### ######## #############
84de38d73f 2007-10-10       aku:     ## Internal methods
84de38d73f 2007-10-10       aku: 
770a9b576a 2007-11-16       aku:     typevariable mycounter        0 ; # Id counter for csets. Last id used.
5f7acef887 2007-11-10       aku:     typevariable mycstype -array {} ; # Map cstypes to persistent ids.
5f7acef887 2007-11-10       aku: 
5f7acef887 2007-11-10       aku:     typemethod getcstypes {} {
5f7acef887 2007-11-10       aku: 	foreach {tid name} [state run {
5f7acef887 2007-11-10       aku: 	    SELECT tid, name FROM cstype;
5f7acef887 2007-11-10       aku: 	}] { set mycstype($name) $tid }
5f7acef887 2007-11-10       aku: 	return
5f7acef887 2007-11-10       aku:     }
5f7acef887 2007-11-10       aku: 
770a9b576a 2007-11-16       aku:     typemethod loadcounter {} {
770a9b576a 2007-11-16       aku: 	# Initialize the counter from the state
96b7bfb834 2007-11-16       aku: 	set mycounter [state one { SELECT MAX(cid) FROM changeset }]
94c39d6375 2007-11-14       aku: 	return
94c39d6375 2007-11-14       aku:     }
94c39d6375 2007-11-14       aku: 
94c39d6375 2007-11-14       aku:     proc PullInternalSuccessorRevisions {dv revisions} {
08ebab80cd 2007-11-10       aku: 	upvar 1 $dv dependencies
08ebab80cd 2007-11-10       aku: 	set theset ('[join $revisions {','}]')
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	foreach {rid child} [state run "
08ebab80cd 2007-11-10       aku:    -- Primary children
08ebab80cd 2007-11-10       aku: 	    SELECT R.rid, R.child
08ebab80cd 2007-11-10       aku: 	    FROM   revision R
08ebab80cd 2007-11-10       aku: 	    WHERE  R.rid   IN $theset
08ebab80cd 2007-11-10       aku: 	    AND    R.child IS NOT NULL
08ebab80cd 2007-11-10       aku: 	    AND    R.child IN $theset
08ebab80cd 2007-11-10       aku:     UNION
08ebab80cd 2007-11-10       aku:     -- Transition NTDB to trunk
08ebab80cd 2007-11-10       aku: 	    SELECT R.rid, R.dbchild
08ebab80cd 2007-11-10       aku: 	    FROM   revision R
08ebab80cd 2007-11-10       aku: 	    WHERE  R.rid   IN $theset
08ebab80cd 2007-11-10       aku: 	    AND    R.dbchild IS NOT NULL
08ebab80cd 2007-11-10       aku: 	    AND    R.dbchild IN $theset
08ebab80cd 2007-11-10       aku:     UNION
08ebab80cd 2007-11-10       aku:     -- Secondary (branch) children
08ebab80cd 2007-11-10       aku: 	    SELECT R.rid, B.brid
08ebab80cd 2007-11-10       aku: 	    FROM   revision R, revisionbranchchildren B
08ebab80cd 2007-11-10       aku: 	    WHERE  R.rid   IN $theset
08ebab80cd 2007-11-10       aku: 	    AND    R.rid = B.rid
08ebab80cd 2007-11-10       aku: 	    AND    B.brid IN $theset
08ebab80cd 2007-11-10       aku: 	"] {
08ebab80cd 2007-11-10       aku: 	    # Consider moving this to the integrity module.
08ebab80cd 2007-11-10       aku: 	    if {$rid == $child} {
08ebab80cd 2007-11-10       aku: 		trouble internal "Revision $rid depends on itself."
08ebab80cd 2007-11-10       aku: 	    }
94c39d6375 2007-11-14       aku: 	    lappend dependencies($rid) $child
94c39d6375 2007-11-14       aku: 	}
94c39d6375 2007-11-14       aku:     }
94c39d6375 2007-11-14       aku: 
94c39d6375 2007-11-14       aku:     proc PullSuccessorRevisions {dv revisions} {
94c39d6375 2007-11-14       aku: 	upvar 1 $dv dependencies
94c39d6375 2007-11-14       aku: 	set theset ('[join $revisions {','}]')
94c39d6375 2007-11-14       aku: 
184c56327e 2007-11-24       aku: 	# The following cases specify when a revision S is a successor
184c56327e 2007-11-24       aku: 	# of a revision R. Each of the cases translates into one of
184c56327e 2007-11-24       aku: 	# the branches of the SQL UNION coming below.
184c56327e 2007-11-24       aku: 	#
184c56327e 2007-11-24       aku: 	# (1) S can be a primary child of R, i.e. in the same LOD. R
184c56327e 2007-11-24       aku: 	#     references S directly. R.child = S(.rid), if it exists.
184c56327e 2007-11-24       aku: 	#
184c56327e 2007-11-24       aku: 	# (2) S can be a secondary, i.e. branch, child of R. Here the
184c56327e 2007-11-24       aku: 	#     link is made through the helper table
184c56327e 2007-11-24       aku: 	#     REVISIONBRANCHCHILDREN. R.rid -> RBC.rid, RBC.brid =
184c56327e 2007-11-24       aku: 	#     S(.rid)
184c56327e 2007-11-24       aku: 	#
184c56327e 2007-11-24       aku: 	# (3) If R is the trunk root of its file and S is the root of
184c56327e 2007-11-24       aku: 	#     the NTDB of the same file, then S is a successor of
184c56327e 2007-11-24       aku: 	#     R. There is no direct link between the two in the
184c56327e 2007-11-24       aku: 	#     database. An indirect link can be made through the FILE
184c56327e 2007-11-24       aku: 	#     they belong too, and their combination of attributes to
184c56327e 2007-11-24       aku: 	#     identify them. We check R for trunk rootness and then
184c56327e 2007-11-24       aku: 	#     select for the NTDB root, crossing the table with
184c56327e 2007-11-24       aku: 	#     itself.
184c56327e 2007-11-24       aku: 	#
184c56327e 2007-11-24       aku: 	# (4) If R is the last of the NTDB revisions which belong to
184c56327e 2007-11-24       aku: 	#     the trunk, then the primary child of the trunk root (the
184c56327e 2007-11-24       aku: 	#     '1.2' revision) is a successor, if it exists.
184c56327e 2007-11-24       aku: 
94c39d6375 2007-11-14       aku: 	foreach {rid child} [state run "
184c56327e 2007-11-24       aku:    -- (1) Primary child
94c39d6375 2007-11-14       aku: 	    SELECT R.rid, R.child
94c39d6375 2007-11-14       aku: 	    FROM   revision R
184c56327e 2007-11-24       aku: 	    WHERE  R.rid   IN $theset     -- Restrict to revisions of interest
184c56327e 2007-11-24       aku: 	    AND    R.child IS NOT NULL    -- Has primary child
94c39d6375 2007-11-14       aku:     UNION
184c56327e 2007-11-24       aku:     -- (2) Secondary (branch) children
94c39d6375 2007-11-14       aku: 	    SELECT R.rid, B.brid
94c39d6375 2007-11-14       aku: 	    FROM   revision R, revisionbranchchildren B
184c56327e 2007-11-24       aku: 	    WHERE  R.rid   IN $theset     -- Restrict to revisions of interest
184c56327e 2007-11-24       aku: 	    AND    R.rid = B.rid          -- Select subset of branch children
184c56327e 2007-11-24       aku:     UNION
184c56327e 2007-11-24       aku:     -- (3) NTDB root successor of Trunk root
184c56327e 2007-11-24       aku: 	    SELECT R.rid, RX.rid
184c56327e 2007-11-24       aku: 	    FROM   revision R, revision RX
184c56327e 2007-11-24       aku: 	    WHERE  R.rid   IN $theset     -- Restrict to revisions of interest
184c56327e 2007-11-24       aku: 	    AND    R.parent IS NULL       -- Restrict to root
184c56327e 2007-11-24       aku: 	    AND    NOT R.isdefault        -- on the trunk
184c56327e 2007-11-24       aku: 	    AND    R.fid = RX.fid         -- Select all revision in the same file
184c56327e 2007-11-24       aku: 	    AND    RX.parent IS NULL      -- Restrict to root
184c56327e 2007-11-24       aku: 	    AND    RX.isdefault           -- on the NTDB
184c56327e 2007-11-24       aku:     UNION
184c56327e 2007-11-24       aku:     -- (4) Child of trunk root successor of last NTDB on trunk.
184c56327e 2007-11-24       aku: 	    SELECT R.rid, RA.child
184c56327e 2007-11-24       aku: 	    FROM revision R, revision RA
184c56327e 2007-11-24       aku: 	    WHERE R.rid   IN $theset      -- Restrict to revisions of interest
184c56327e 2007-11-24       aku: 	    AND   R.isdefault             -- Restrict to NTDB
184c56327e 2007-11-24       aku: 	    AND   R.dbchild IS NOT NULL   -- and last NTDB belonging to trunk
184c56327e 2007-11-24       aku: 	    AND   RA.rid = R.dbchild      -- Go directly to trunk root
184c56327e 2007-11-24       aku: 	    AND   RA.child IS NOT NULL    -- Has primary child.
94c39d6375 2007-11-14       aku: 	"] {
94c39d6375 2007-11-14       aku: 	    # Consider moving this to the integrity module.
94c39d6375 2007-11-14       aku: 	    if {$rid == $child} {
94c39d6375 2007-11-14       aku: 		trouble internal "Revision $rid depends on itself."
94c39d6375 2007-11-14       aku: 	    }
94c39d6375 2007-11-14       aku: 	    lappend dependencies($rid) $child
94c39d6375 2007-11-14       aku: 	}
eabaea870a 2007-11-24       aku: 	return
e50f9ed55e 2007-11-22       aku:     }
e50f9ed55e 2007-11-22       aku: 
e50f9ed55e 2007-11-22       aku:     proc PullPredecessorRevisions {dv revisions} {
e50f9ed55e 2007-11-22       aku: 	upvar 1 $dv dependencies
e50f9ed55e 2007-11-22       aku: 	set theset ('[join $revisions {','}]')
e50f9ed55e 2007-11-22       aku: 
184c56327e 2007-11-24       aku: 	# The following cases specify when a revision P is a
184c56327e 2007-11-24       aku: 	# predecessor of a revision R. Each of the cases translates
184c56327e 2007-11-24       aku: 	# into one of the branches of the SQL UNION coming below.
184c56327e 2007-11-24       aku: 	#
184c56327e 2007-11-24       aku: 	# (1) The immediate parent R.parent of R is a predecessor of
184c56327e 2007-11-24       aku: 	#     R. NOTE: This is true for R either primary or secondary
184c56327e 2007-11-24       aku: 	#     child of P. It not necessary to distinguish the two
184c56327e 2007-11-24       aku: 	#     cases, in contrast to the code retrieving the successor
184c56327e 2007-11-24       aku: 	#     information.
184c56327e 2007-11-24       aku: 	#
184c56327e 2007-11-24       aku: 	# (2) The complement of successor case (3). The trunk root is
184c56327e 2007-11-24       aku: 	#     a predecessor of a NTDB root.
184c56327e 2007-11-24       aku: 	#
184c56327e 2007-11-24       aku: 	# (3) The complement of successor case (4). The last NTDB
184c56327e 2007-11-24       aku: 	#     revision belonging to the trunk is a predecessor of the
184c56327e 2007-11-24       aku: 	#     primary child of the trunk root (The '1.2' revision).
184c56327e 2007-11-24       aku: 
e50f9ed55e 2007-11-22       aku: 	foreach {rid parent} [state run "
184c56327e 2007-11-24       aku:    -- (1) Primary parent, can be in different LOD for first in a branch
e50f9ed55e 2007-11-22       aku: 	    SELECT R.rid, R.parent
e50f9ed55e 2007-11-22       aku: 	    FROM   revision R
184c56327e 2007-11-24       aku: 	    WHERE  R.rid   IN $theset     -- Restrict to revisions of interest
184c56327e 2007-11-24       aku: 	    AND    R.parent IS NOT NULL   -- Has primary parent
184c56327e 2007-11-24       aku:     UNION
184c56327e 2007-11-24       aku:     -- (2) Trunk root predecessor of NTDB root.
184c56327e 2007-11-24       aku: 	    SELECT R.rid, RX.rid
184c56327e 2007-11-24       aku: 	    FROM   revision R, revision RX
184c56327e 2007-11-24       aku: 	    WHERE  R.rid IN $theset     -- Restrict to revisions of interest
184c56327e 2007-11-24       aku: 	    AND    R.parent IS NULL     -- which are root
184c56327e 2007-11-24       aku: 	    AND    R.isdefault          -- on NTDB
184c56327e 2007-11-24       aku: 	    AND    R.fid = RX.fid       -- Select all revision in the same file
184c56327e 2007-11-24       aku: 	    AND    RX.parent IS NULL    -- which are root
184c56327e 2007-11-24       aku: 	    AND    NOT RX.isdefault     -- on the trunk
e50f9ed55e 2007-11-22       aku:     UNION
184c56327e 2007-11-24       aku:     -- (3) Last NTDB on trunk is predecessor of child of trunk root
184c56327e 2007-11-24       aku: 	    SELECT R.rid, RA.dbparent
184c56327e 2007-11-24       aku: 	    FROM revision R, revision RA
184c56327e 2007-11-24       aku: 	    WHERE R.rid IN $theset       -- Restrict to revisions of interest
184c56327e 2007-11-24       aku: 	    AND NOT R.isdefault          -- not on NTDB
184c56327e 2007-11-24       aku: 	    AND R.parent IS NOT NULL     -- which are not root
184c56327e 2007-11-24       aku: 	    AND RA.rid = R.parent        -- go to their parent
184c56327e 2007-11-24       aku: 	    AND RA.dbparent IS NOT NULL  -- which has to refer to NTDB's root
e50f9ed55e 2007-11-22       aku: 	"] {
e50f9ed55e 2007-11-22       aku: 	    # Consider moving this to the integrity module.
e50f9ed55e 2007-11-22       aku: 	    if {$rid == $parent} {
e50f9ed55e 2007-11-22       aku: 		trouble internal "Revision $rid depends on itself."
e50f9ed55e 2007-11-22       aku: 	    }
e50f9ed55e 2007-11-22       aku: 	    lappend dependencies($rid) $parent
08ebab80cd 2007-11-10       aku: 	}
eabaea870a 2007-11-24       aku: 	return
08ebab80cd 2007-11-10       aku:     }
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku:     proc InitializeBreakState {revisions} {
08ebab80cd 2007-11-10       aku: 	upvar 1 pos pos cross cross range range depc depc delta delta \
08ebab80cd 2007-11-10       aku: 	    dependencies dependencies
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	# First we create a map of positions to make it easier to
08ebab80cd 2007-11-10       aku: 	# determine whether a dependency crosses a particular index.
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	array set pos   {}
08ebab80cd 2007-11-10       aku: 	array set cross {}
08ebab80cd 2007-11-10       aku: 	array set depc  {}
08ebab80cd 2007-11-10       aku: 	set range       {}
08ebab80cd 2007-11-10       aku: 	set n 0
08ebab80cd 2007-11-10       aku: 	foreach rev $revisions {
08ebab80cd 2007-11-10       aku: 	    lappend range $n
08ebab80cd 2007-11-10       aku: 	    set pos($rev) $n
08ebab80cd 2007-11-10       aku: 	    set cross($n) 0
08ebab80cd 2007-11-10       aku: 	    incr n
08ebab80cd 2007-11-10       aku: 	}
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	# Secondly we count the crossings per position, by iterating
08ebab80cd 2007-11-10       aku: 	# over the recorded internal dependencies.
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	# Note: If the timestamps are badly out of order it is
08ebab80cd 2007-11-10       aku: 	#       possible to have a backward successor dependency,
08ebab80cd 2007-11-10       aku: 	#       i.e. with start > end. We may have to swap the indices
08ebab80cd 2007-11-10       aku: 	#       to ensure that the following loop runs correctly.
08ebab80cd 2007-11-10       aku: 	#
08ebab80cd 2007-11-10       aku: 	# Note 2: start == end is not possible. It indicates a
08ebab80cd 2007-11-10       aku: 	#         self-dependency due to the uniqueness of positions,
08ebab80cd 2007-11-10       aku: 	#         and that is something we have ruled out already, see
94c39d6375 2007-11-14       aku: 	#         PullInternalSuccessorRevisions.
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	foreach {rid child} [array get dependencies] {
08ebab80cd 2007-11-10       aku: 	    set dkey    [list $rid $child]
08ebab80cd 2007-11-10       aku: 	    set start   $pos($rid)
08ebab80cd 2007-11-10       aku: 	    set end     $pos($child)
08ebab80cd 2007-11-10       aku: 	    set crosses {}
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	    if {$start > $end} {
08ebab80cd 2007-11-10       aku: 		while {$end < $start} {
08ebab80cd 2007-11-10       aku: 		    lappend crosses $end
08ebab80cd 2007-11-10       aku: 		    incr cross($end)
08ebab80cd 2007-11-10       aku: 		    incr end
08ebab80cd 2007-11-10       aku: 		}
08ebab80cd 2007-11-10       aku: 	    } else {
08ebab80cd 2007-11-10       aku: 		while {$start < $end} {
08ebab80cd 2007-11-10       aku: 		    lappend crosses $start
08ebab80cd 2007-11-10       aku: 		    incr cross($start)
08ebab80cd 2007-11-10       aku: 		    incr start
08ebab80cd 2007-11-10       aku: 		}
08ebab80cd 2007-11-10       aku: 	    }
08ebab80cd 2007-11-10       aku: 	    set depc($dkey) $crosses
08ebab80cd 2007-11-10       aku: 	}
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	InitializeDeltas $revisions
08ebab80cd 2007-11-10       aku: 	return
08ebab80cd 2007-11-10       aku:     }
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku:     proc InitializeDeltas {revisions} {
08ebab80cd 2007-11-10       aku: 	upvar 1 delta delta
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	# Pull the timestamps for all revisions in the changesets and
08ebab80cd 2007-11-10       aku: 	# compute their deltas for use by the break finder.
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	array set delta {}
08ebab80cd 2007-11-10       aku: 	array set stamp {}
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	set theset ('[join $revisions {','}]')
08ebab80cd 2007-11-10       aku: 	foreach {rid time} [state run "
08ebab80cd 2007-11-10       aku: 	    SELECT R.rid, R.date
08ebab80cd 2007-11-10       aku: 	    FROM revision R
08ebab80cd 2007-11-10       aku: 	    WHERE R.rid IN $theset
08ebab80cd 2007-11-10       aku: 	"] {
08ebab80cd 2007-11-10       aku: 	    set stamp($rid) $time
08ebab80cd 2007-11-10       aku: 	}
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	set n 0
08ebab80cd 2007-11-10       aku: 	foreach rid [lrange $revisions 0 end-1] rnext [lrange $revisions 1 end] {
08ebab80cd 2007-11-10       aku: 	    set delta($n) [expr {$stamp($rnext) - $stamp($rid)}]
08ebab80cd 2007-11-10       aku: 	    incr n
08ebab80cd 2007-11-10       aku: 	}
08ebab80cd 2007-11-10       aku: 	return
08ebab80cd 2007-11-10       aku:     }
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku:     proc FindBestBreak {range} {
08ebab80cd 2007-11-10       aku: 	upvar 1 cross cross delta delta
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	# Determine the best break location in the given range of
08ebab80cd 2007-11-10       aku: 	# positions. First we look for the locations with the maximal
08ebab80cd 2007-11-10       aku: 	# number of crossings. If there are several we look for the
08ebab80cd 2007-11-10       aku: 	# shortest time interval among them. If we still have multiple
08ebab80cd 2007-11-10       aku: 	# possibilities after that we select the earliest location
08ebab80cd 2007-11-10       aku: 	# among these.
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	# Note: If the maximal number of crossings is 0 then the range
08ebab80cd 2007-11-10       aku: 	#       has no internal dependencies, and no break location at
08ebab80cd 2007-11-10       aku: 	#       all. This possibility is signaled via result -1.
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	# Note: A range of length 1 or less cannot have internal
08ebab80cd 2007-11-10       aku: 	#       dependencies, as that needs at least two revisions in
08ebab80cd 2007-11-10       aku: 	#       the range.
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	if {[llength $range] < 2} { return -1 }
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	set max -1
08ebab80cd 2007-11-10       aku: 	set best {}
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	foreach location $range {
08ebab80cd 2007-11-10       aku: 	    set crossings $cross($location)
08ebab80cd 2007-11-10       aku: 	    if {$crossings > $max} {
08ebab80cd 2007-11-10       aku: 		set max  $crossings
08ebab80cd 2007-11-10       aku: 		set best [list $location]
08ebab80cd 2007-11-10       aku: 		continue
08ebab80cd 2007-11-10       aku: 	    } elseif {$crossings == $max} {
08ebab80cd 2007-11-10       aku: 		lappend best $location
08ebab80cd 2007-11-10       aku: 	    }
08ebab80cd 2007-11-10       aku: 	}
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	if {$max == 0}            { return -1 }
08ebab80cd 2007-11-10       aku: 	if {[llength $best] == 1} { return [lindex $best 0] }
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	set locations $best
08ebab80cd 2007-11-10       aku: 	set best {}
08ebab80cd 2007-11-10       aku: 	set min -1
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	foreach location $locations {
08ebab80cd 2007-11-10       aku: 	    set interval $delta($location)
08ebab80cd 2007-11-10       aku: 	    if {($min < 0) || ($interval < $min)} {
08ebab80cd 2007-11-10       aku: 		set min  $interval
08ebab80cd 2007-11-10       aku: 		set best [list $location]
08ebab80cd 2007-11-10       aku: 	    } elseif {$interval == $min} {
08ebab80cd 2007-11-10       aku: 		lappend best $location
08ebab80cd 2007-11-10       aku: 	    }
08ebab80cd 2007-11-10       aku: 	}
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	if {[llength $best] == 1} { return [lindex $best 0] }
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	return [lindex [lsort -integer -increasing $best] 0]
08ebab80cd 2007-11-10       aku:     }
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku:     proc CutAt {location} {
08ebab80cd 2007-11-10       aku: 	upvar 1 cross cross depc depc
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	# It was decided to split the changeset at the given
08ebab80cd 2007-11-10       aku: 	# location. This cuts a number of dependencies. Here we update
08ebab80cd 2007-11-10       aku: 	# the cross information so that the break finder has accurate
08ebab80cd 2007-11-10       aku: 	# data when we look at the generated fragments.
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	set six [log visible? 6]
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	foreach {dep range} [array get depc] {
08ebab80cd 2007-11-10       aku: 	    # Check all dependencies still known, take their range and
08ebab80cd 2007-11-10       aku: 	    # see if the break location falls within.
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	    Border $range s e
08ebab80cd 2007-11-10       aku: 	    if {$location < $s} continue ; # break before range, ignore
08ebab80cd 2007-11-10       aku: 	    if {$location > $e} continue ; # break after range, ignore.
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	    # This dependency crosses the break location. We remove it
08ebab80cd 2007-11-10       aku: 	    # from the crossings counters, and then also from the set
08ebab80cd 2007-11-10       aku: 	    # of known dependencies, as we are done with it.
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	    foreach loc $depc($dep) { incr cross($loc) -1 }
08ebab80cd 2007-11-10       aku: 	    unset depc($dep)
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	    if {!$six} continue
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	    struct::list assign $dep parent child
08ebab80cd 2007-11-10       aku: 	    log write 6 csets "Broke dependency [PD $parent] --> [PD $child]"
08ebab80cd 2007-11-10       aku: 	}
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	return
08ebab80cd 2007-11-10       aku:     }
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku:     # Print identifying data for a revision (project, file, dotted rev
08ebab80cd 2007-11-10       aku:     # number), for high verbosity log output.
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku:     proc PD {id} {
08ebab80cd 2007-11-10       aku: 	foreach {p f r} [state run {
08ebab80cd 2007-11-10       aku: 		SELECT P.name , F.name, R.rev
08ebab80cd 2007-11-10       aku: 		FROM revision R, file F, project P
08ebab80cd 2007-11-10       aku: 		WHERE R.rid = $id
08ebab80cd 2007-11-10       aku: 		AND   R.fid = F.fid
08ebab80cd 2007-11-10       aku: 		AND   F.pid = P.pid
08ebab80cd 2007-11-10       aku: 	}] break
08ebab80cd 2007-11-10       aku: 	return "'$p : $f/$r'"
08ebab80cd 2007-11-10       aku:     }
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku:     # Printing one or more ranges, formatted, and only their border to
08ebab80cd 2007-11-10       aku:     # keep the strings short.
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku:     proc PRs {ranges} {
08ebab80cd 2007-11-10       aku: 	return [struct::list map $ranges [myproc PR]]
08ebab80cd 2007-11-10       aku:     }
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku:     proc PR {range} {
08ebab80cd 2007-11-10       aku: 	Border $range s e
08ebab80cd 2007-11-10       aku: 	return <${s}...${e}>
08ebab80cd 2007-11-10       aku:     }
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku:     proc Border {range sv ev} {
08ebab80cd 2007-11-10       aku: 	upvar 1 $sv s $ev e
08ebab80cd 2007-11-10       aku: 	set s [lindex $range 0]
08ebab80cd 2007-11-10       aku: 	set e [lindex $range end]
08ebab80cd 2007-11-10       aku: 	return
08ebab80cd 2007-11-10       aku:     }
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku:     # # ## ### ##### ######## #############
24c0b662de 2007-11-13       aku: 
85bd219d0b 2007-11-13       aku:     typevariable mychangesets    {} ; # List of all known changesets.
8c9030e3e8 2007-11-24       aku:     typevariable myrevmap -array {} ; # Map from revisions to the list
8c9030e3e8 2007-11-24       aku: 				      # of changesets containing
8c9030e3e8 2007-11-24       aku: 				      # it. NOTE: While only one
8c9030e3e8 2007-11-24       aku: 				      # revision changeset can contain
8c9030e3e8 2007-11-24       aku: 				      # the revision, there can
8c9030e3e8 2007-11-24       aku: 				      # however also be one or more
8c9030e3e8 2007-11-24       aku: 				      # additional symbol changesets
8c9030e3e8 2007-11-24       aku: 				      # which use it, hence a list.
de4cff4142 2007-11-22       aku:     typevariable myidmap  -array {} ; # Map from changeset id to changeset.
4866889e88 2007-11-22       aku:     typevariable mybranchcode    {} ; # Local copy of project::sym/mybranch.
24c0b662de 2007-11-13       aku: 
e50f9ed55e 2007-11-22       aku:     typemethod all   {}   { return $mychangesets }
e50f9ed55e 2007-11-22       aku:     typemethod of    {id} { return $myidmap($id) }
e50f9ed55e 2007-11-22       aku:     typemethod ofrev {id} { return $myrevmap($id) }
24c0b662de 2007-11-13       aku: 
84de38d73f 2007-10-10       aku:     # # ## ### ##### ######## #############
84de38d73f 2007-10-10       aku:     ## Configuration
84de38d73f 2007-10-10       aku: 
84de38d73f 2007-10-10       aku:     pragma -hastypeinfo    no  ; # no type introspection
84de38d73f 2007-10-10       aku:     pragma -hasinfo        no  ; # no object introspection
84de38d73f 2007-10-10       aku:     pragma -simpledispatch yes ; # simple fast dispatch
84de38d73f 2007-10-10       aku: 
84de38d73f 2007-10-10       aku:     # # ## ### ##### ######## #############
84de38d73f 2007-10-10       aku: }
84de38d73f 2007-10-10       aku: 
84de38d73f 2007-10-10       aku: namespace eval ::vc::fossil::import::cvs::project {
84de38d73f 2007-10-10       aku:     namespace export rev
5f7acef887 2007-11-10       aku:     namespace eval rev {
5f7acef887 2007-11-10       aku: 	namespace import ::vc::fossil::import::cvs::state
4866889e88 2007-11-22       aku: 	namespace eval project {
4866889e88 2007-11-22       aku: 	    namespace import ::vc::fossil::import::cvs::project::sym
4866889e88 2007-11-22       aku: 	}
47e271a448 2007-11-22       aku: 	::variable mybranchcode [project::sym branch]
08ebab80cd 2007-11-10       aku: 	namespace import ::vc::tools::misc::*
08ebab80cd 2007-11-10       aku: 	namespace import ::vc::tools::trouble
95af789e1f 2007-11-10       aku: 	namespace import ::vc::tools::log
95af789e1f 2007-11-10       aku: 	log register csets
5f7acef887 2007-11-10       aku:     }
84de38d73f 2007-10-10       aku: }
84de38d73f 2007-10-10       aku: 
84de38d73f 2007-10-10       aku: # # ## ### ##### ######## ############# #####################
84de38d73f 2007-10-10       aku: ## Ready
84de38d73f 2007-10-10       aku: 
84de38d73f 2007-10-10       aku: package provide vc::fossil::import::cvs::project::rev 1.0
84de38d73f 2007-10-10       aku: return