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.
b42cff97e3 2007-11-30       aku: package require struct::set                           ; # Set operations.
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.
47d52d1efd 2007-11-28       aku: package require vc::fossil::import::cvs::integrity    ; # State integrity checks.
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: 
deab4d035b 2007-11-29       aku:     constructor {project cstype srcid items {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: 
b42cff97e3 2007-11-30       aku: 	integrity assert {
b42cff97e3 2007-11-30       aku: 	    [info exists mycstype($cstype)]
b42cff97e3 2007-11-30       aku: 	} {Bad changeset type '$cstype'.}
c74fe3de3f 2007-11-29       aku: 
5f7acef887 2007-11-10       aku: 	set myproject   $project
5f7acef887 2007-11-10       aku: 	set mytype      $cstype
c74fe3de3f 2007-11-29       aku: 	set mytypeobj   ::vc::fossil::import::cvs::project::rev::${cstype}
5f7acef887 2007-11-10       aku: 	set mysrcid	$srcid
deab4d035b 2007-11-29       aku: 	set myitems     $items
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
deab4d035b 2007-11-29       aku: 	# mapping from items to them.
de4cff4142 2007-11-22       aku: 	lappend mychangesets   $self
de4cff4142 2007-11-22       aku: 	set     myidmap($myid) $self
deab4d035b 2007-11-29       aku: 	foreach iid $items {
deab4d035b 2007-11-29       aku: 	    set key [list $cstype $iid]
deab4d035b 2007-11-29       aku: 	    set myitemmap($key) $self
0fcfbf7828 2007-11-29       aku: 	    lappend mytitems $key
b42cff97e3 2007-11-30       aku: 	    log write 8 csets {MAP+ item <$key> $self = [$self str]}
0fcfbf7828 2007-11-29       aku: 	}
911d56a8c8 2007-11-27       aku: 	return
911d56a8c8 2007-11-27       aku:     }
911d56a8c8 2007-11-27       aku: 
911d56a8c8 2007-11-27       aku:     method str {} {
911d56a8c8 2007-11-27       aku: 	set str    "<"
911d56a8c8 2007-11-27       aku: 	set detail ""
70d2283564 2007-11-29       aku: 	if {[$mytypeobj bysymbol]} {
70d2283564 2007-11-29       aku: 	    set detail " '[state one {
70d2283564 2007-11-29       aku: 		SELECT S.name
70d2283564 2007-11-29       aku: 		FROM   symbol S
911d56a8c8 2007-11-27       aku: 		WHERE  S.sid = $mysrcid
70d2283564 2007-11-29       aku: 	    }]'"
911d56a8c8 2007-11-27       aku: 	}
911d56a8c8 2007-11-27       aku: 	append str "$mytype ${myid}${detail}>"
911d56a8c8 2007-11-27       aku: 	return $str
911d56a8c8 2007-11-27       aku:     }
911d56a8c8 2007-11-27       aku: 
61829b076b 2007-11-29       aku:     method id    {} { return $myid }
61829b076b 2007-11-29       aku:     method items {} { return $mytitems }
61829b076b 2007-11-29       aku:     method data  {} { return [list $myproject $mytype $mysrcid] }
c74fe3de3f 2007-11-29       aku: 
c74fe3de3f 2007-11-29       aku:     delegate method bysymbol   to mytypeobj
c74fe3de3f 2007-11-29       aku:     delegate method byrevision to mytypeobj
c74fe3de3f 2007-11-29       aku:     delegate method isbranch   to mytypeobj
c74fe3de3f 2007-11-29       aku:     delegate method istag      to mytypeobj
de4cff4142 2007-11-22       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: 
9c57055025 2007-12-02       aku:     # result = list (changeset)
85bd219d0b 2007-11-13       aku:     method successors {} {
9c57055025 2007-12-02       aku: 	return [struct::list map \
9c57055025 2007-12-02       aku: 		    [$mytypeobj cs_successors $myitems] \
9c57055025 2007-12-02       aku: 		    [mytypemethod of]]
9c57055025 2007-12-02       aku:     }
9c57055025 2007-12-02       aku: 
0fcfbf7828 2007-11-29       aku:     # result = dict (item -> list (changeset))
e50f9ed55e 2007-11-22       aku:     method successormap {} {
9c57055025 2007-12-02       aku: 	# NOTE / FUTURE: Definitive bottleneck (can be millions of pairs).
9c57055025 2007-12-02       aku: 	#
9c57055025 2007-12-02       aku: 	# Only user is pass 9, computing the limits of backward
9c57055025 2007-12-02       aku: 	# branches per branch in the changeset. TODO: Fold that into
9c57055025 2007-12-02       aku: 	# the SQL query, i.e. move the crunching from Tcl to C.
9c57055025 2007-12-02       aku: 
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 {
39e19c0cf3 2007-11-29       aku: 		lappend tmp($rev) $myitemmap($child)
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:     }
e50f9ed55e 2007-11-22       aku: 
0fcfbf7828 2007-11-29       aku:     # result = dict (item -> list (changeset))
e50f9ed55e 2007-11-22       aku:     method predecessormap {} {
9c57055025 2007-12-02       aku: 	# NOTE / FUTURE: Definitive bottleneck (can be millions of pairs).
9c57055025 2007-12-02       aku: 	#
9c57055025 2007-12-02       aku: 	# Only user is pass 9, computing the limits of backward
9c57055025 2007-12-02       aku: 	# branches per branch in the changeset. TODO: Fold that into
9c57055025 2007-12-02       aku: 	# the SQL query, i.e. move the crunching from Tcl to C.
9c57055025 2007-12-02       aku: 
e50f9ed55e 2007-11-22       aku: 	array set tmp {}
e50f9ed55e 2007-11-22       aku: 	foreach {rev children} [$self premap] {
94c39d6375 2007-11-14       aku: 	    foreach child $children {
39e19c0cf3 2007-11-29       aku: 		lappend tmp($rev) $myitemmap($child)
94c39d6375 2007-11-14       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:     }
e50f9ed55e 2007-11-22       aku: 
0fcfbf7828 2007-11-29       aku:     # item -> list (item)
94c39d6375 2007-11-14       aku:     method nextmap {} {
ac02614803 2007-12-02       aku: 	#if {[llength $mynextmap]} { return $mynextmap }
deab4d035b 2007-11-29       aku: 	$mytypeobj successors tmp $myitems
ac02614803 2007-12-02       aku: 	return [array get tmp]
ac02614803 2007-12-02       aku: 	#set mynextmap [array get tmp]
ac02614803 2007-12-02       aku: 	#return $mynextmap
0fcfbf7828 2007-11-29       aku:     }
0fcfbf7828 2007-11-29       aku: 
0fcfbf7828 2007-11-29       aku:     # item -> list (item)
e50f9ed55e 2007-11-22       aku:     method premap {} {
ac02614803 2007-12-02       aku: 	#if {[llength $mypremap]} { return $mypremap }
deab4d035b 2007-11-29       aku: 	$mytypeobj predecessors tmp $myitems
87cf609021 2007-11-24       aku: 	return [array get tmp]
ac02614803 2007-12-02       aku: 	#set mypremap [array get tmp]
ac02614803 2007-12-02       aku: 	#return $mypremap
85bd219d0b 2007-11-13       aku:     }
24c0b662de 2007-11-13       aku: 
24c0b662de 2007-11-13       aku:     method breakinternaldependencies {} {
c14e8f84cd 2007-11-30       aku: 
c14e8f84cd 2007-11-30       aku: 	##
c14e8f84cd 2007-11-30       aku: 	## NOTE: This method, maybe in conjunction with its caller
c14e8f84cd 2007-11-30       aku: 	##       seems to be a memory hog, especially for large
c14e8f84cd 2007-11-30       aku: 	##       changesets, with 'large' meaning to have a 'long list
c14e8f84cd 2007-11-30       aku: 	##       of items, several thousand'. Investigate where the
c14e8f84cd 2007-11-30       aku: 	##       memory is spent and then look for ways of rectifying
c14e8f84cd 2007-11-30       aku: 	##       the problem.
c14e8f84cd 2007-11-30       aku: 	##
95af789e1f 2007-11-10       aku: 
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 {}
deab4d035b 2007-11-29       aku: 	$mytypeobj internalsuccessors dependencies $myitems
95af789e1f 2007-11-10       aku: 	if {![array size dependencies]} {return 0} ; # Nothing to break.
08ebab80cd 2007-11-10       aku: 
911d56a8c8 2007-11-27       aku: 	log write 5 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: 
deab4d035b 2007-11-29       aku: 	InitializeBreakState $myitems
08ebab80cd 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	set fragments {}
c14e8f84cd 2007-11-30       aku: 	set new       [list $range]
08ebab80cd 2007-11-10       aku: 	array set breaks {}
08ebab80cd 2007-11-10       aku: 
c14e8f84cd 2007-11-30       aku: 	# Instead of one list holding both processed and pending
c14e8f84cd 2007-11-30       aku: 	# fragments we use two, one for the framents to process, one
c14e8f84cd 2007-11-30       aku: 	# to hold the new fragments, and the latter is copied to the
c14e8f84cd 2007-11-30       aku: 	# former when they run out. This keeps the list of pending
c14e8f84cd 2007-11-30       aku: 	# fragments short without sacrificing speed by shifting stuff
c14e8f84cd 2007-11-30       aku: 	# down. We especially drop the memory of fragments broken
c14e8f84cd 2007-11-30       aku: 	# during processing after a short time, instead of letting it
c14e8f84cd 2007-11-30       aku: 	# consume memory.
c14e8f84cd 2007-11-30       aku: 
c14e8f84cd 2007-11-30       aku: 	while {[llength $new]} {
c14e8f84cd 2007-11-30       aku: 
c14e8f84cd 2007-11-30       aku: 	    set pending $new
c14e8f84cd 2007-11-30       aku: 	    set new     {}
c14e8f84cd 2007-11-30       aku: 	    set at      0
c14e8f84cd 2007-11-30       aku: 
c14e8f84cd 2007-11-30       aku: 	    while {$at < [llength $pending]} {
c14e8f84cd 2007-11-30       aku: 		set current [lindex $pending $at]
c14e8f84cd 2007-11-30       aku: 
c14e8f84cd 2007-11-30       aku: 		log write 6 csets {. . .. ... ..... ........ .............}
c14e8f84cd 2007-11-30       aku: 		log write 6 csets {Scheduled   [join [PRs [lrange $pending $at end]] { }]}
c14e8f84cd 2007-11-30       aku: 		log write 6 csets {Considering [PR $current] \[$at/[llength $pending]\]}
c14e8f84cd 2007-11-30       aku: 
c14e8f84cd 2007-11-30       aku: 		set best [FindBestBreak $current]
c14e8f84cd 2007-11-30       aku: 
c14e8f84cd 2007-11-30       aku: 		if {$best < 0} {
c14e8f84cd 2007-11-30       aku: 		    # The inspected range has no internal
c14e8f84cd 2007-11-30       aku: 		    # dependencies. This is a complete fragment.
c14e8f84cd 2007-11-30       aku: 		    lappend fragments $current
c14e8f84cd 2007-11-30       aku: 
c14e8f84cd 2007-11-30       aku: 		    log write 6 csets "No breaks, final"
c14e8f84cd 2007-11-30       aku: 		} else {
c14e8f84cd 2007-11-30       aku: 		    # Split the range and schedule the resulting
c14e8f84cd 2007-11-30       aku: 		    # fragments for further inspection. Remember the
c14e8f84cd 2007-11-30       aku: 		    # number of dependencies cut before we remove them
c14e8f84cd 2007-11-30       aku: 		    # from consideration, for documentation later.
c14e8f84cd 2007-11-30       aku: 
c14e8f84cd 2007-11-30       aku: 		    set breaks($best) $cross($best)
c14e8f84cd 2007-11-30       aku: 
c14e8f84cd 2007-11-30       aku: 		    log write 6 csets "Best break @ $best, cutting [nsp $cross($best) dependency dependencies]"
c14e8f84cd 2007-11-30       aku: 
c14e8f84cd 2007-11-30       aku: 		    # Note: The value of best is an abolute location
c14e8f84cd 2007-11-30       aku: 		    # in myitems. Use the start of current to make it
c14e8f84cd 2007-11-30       aku: 		    # an index absolute to current.
c14e8f84cd 2007-11-30       aku: 
c14e8f84cd 2007-11-30       aku: 		    set brel [expr {$best - [lindex $current 0]}]
c14e8f84cd 2007-11-30       aku: 		    set bnext $brel ; incr bnext
c14e8f84cd 2007-11-30       aku: 		    set fragbefore [lrange $current 0 $brel]
c14e8f84cd 2007-11-30       aku: 		    set fragafter  [lrange $current $bnext end]
c14e8f84cd 2007-11-30       aku: 
c14e8f84cd 2007-11-30       aku: 		    log write 6 csets "New pieces  [PR $fragbefore] [PR $fragafter]"
c14e8f84cd 2007-11-30       aku: 
c14e8f84cd 2007-11-30       aku: 		    integrity assert {[llength $fragbefore]} {Found zero-length fragment at the beginning}
c14e8f84cd 2007-11-30       aku: 		    integrity assert {[llength $fragafter]}  {Found zero-length fragment at the end}
c14e8f84cd 2007-11-30       aku: 
c14e8f84cd 2007-11-30       aku: 		    lappend new $fragbefore $fragafter
c14e8f84cd 2007-11-30       aku: 		    CutAt $best
08ebab80cd 2007-11-10       aku: 		}
08ebab80cd 2007-11-10       aku: 
c14e8f84cd 2007-11-30       aku: 		incr at
95af789e1f 2007-11-10       aku: 	    }
95af789e1f 2007-11-10       aku: 	}
95af789e1f 2007-11-10       aku: 
08ebab80cd 2007-11-10       aku: 	log write 6 csets ". . .. ... ..... ........ ............."
17ec2d682c 2007-11-24       aku: 
deab4d035b 2007-11-29       aku: 	# (*) We clear out the associated part of the myitemmap
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: 
deab4d035b 2007-11-29       aku: 	foreach iid $myitems {
deab4d035b 2007-11-29       aku: 	    set key [list $mytype $iid]
deab4d035b 2007-11-29       aku: 	    unset myitemmap($key)
b42cff97e3 2007-11-30       aku: 	    log write 8 csets {MAP- item <$key> $self = [$self str]}
0fcfbf7828 2007-11-29       aku: 	}
08ebab80cd 2007-11-10       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: 
47d52d1efd 2007-11-28       aku: 	integrity assert {$firsts == 0} {Bad fragment start @ $firsts, gap, or before beginning of the range}
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
47d52d1efd 2007-11-28       aku: 	    integrity assert {$laste == ($s - 1)} {Bad fragment border <$laste | $s>, gap or overlap}
47d52d1efd 2007-11-28       aku: 
deab4d035b 2007-11-29       aku: 	    set new [$type %AUTO% $myproject $mytype $mysrcid [lrange $myitems $s $e]]
87cf609021 2007-11-24       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: 
47d52d1efd 2007-11-28       aku: 	integrity assert {
deab4d035b 2007-11-29       aku: 	    $laste == ([llength $myitems]-1)
47d52d1efd 2007-11-28       aku: 	} {Bad fragment end @ $laste, gap, or beyond end of the range}
17ec2d682c 2007-11-24       aku: 
17ec2d682c 2007-11-24       aku: 	# Put the first fragment into the current changeset, and
deab4d035b 2007-11-29       aku: 	# update the in-memory index. We can simply (re)add the items
deab4d035b 2007-11-29       aku: 	# because we cleared the previously existing information, see
deab4d035b 2007-11-29       aku: 	# (*) above. Persistence does not matter here, none of the
deab4d035b 2007-11-29       aku: 	# changesets has been saved to the persistent state yet.
deab4d035b 2007-11-29       aku: 
facb4a8721 2007-11-30       aku: 	set myitems  [lrange $myitems  0 $firste]
facb4a8721 2007-11-30       aku: 	set mytitems [lrange $mytitems 0 $firste]
deab4d035b 2007-11-29       aku: 	foreach iid $myitems {
deab4d035b 2007-11-29       aku: 	    set key [list $mytype $iid]
deab4d035b 2007-11-29       aku: 	    set myitemmap($key) $self
b42cff97e3 2007-11-30       aku: 	    log write 8 csets {MAP+ item <$key> $self = [$self str]}
0fcfbf7828 2007-11-29       aku: 	}
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: 
deab4d035b 2007-11-29       aku: 	    foreach iid $myitems {
5f7acef887 2007-11-10       aku: 		state run {
80b1e8936f 2007-11-29       aku: 		    INSERT INTO csitem (cid,   pos,  iid)
80b1e8936f 2007-11-29       aku: 		    VALUES             ($myid, $pos, $iid);
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: 
deab4d035b 2007-11-29       aku:     method timerange {} { return [$mytypeobj timerange $myitems] }
94c39d6375 2007-11-14       aku: 
94c39d6375 2007-11-14       aku:     method drop {} {
b42cff97e3 2007-11-30       aku: 	log write 8 csets {Dropping $self = [$self str]}
b42cff97e3 2007-11-30       aku: 
94c39d6375 2007-11-14       aku: 	state transaction {
94c39d6375 2007-11-14       aku: 	    state run {
80b1e8936f 2007-11-29       aku: 		DELETE FROM changeset WHERE cid = $myid;
80b1e8936f 2007-11-29       aku: 		DELETE FROM csitem    WHERE cid = $myid;
94c39d6375 2007-11-14       aku: 	    }
94c39d6375 2007-11-14       aku: 	}
deab4d035b 2007-11-29       aku: 	foreach iid $myitems {
deab4d035b 2007-11-29       aku: 	    set key [list $mytype $iid]
deab4d035b 2007-11-29       aku: 	    unset myitemmap($key)
b42cff97e3 2007-11-30       aku: 	    log write 8 csets {MAP- item <$key> $self = [$self str]}
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]
94c39d6375 2007-11-14       aku: 	return
94c39d6375 2007-11-14       aku:     }
94c39d6375 2007-11-14       aku: 
0af7a3c8ac 2007-11-30       aku:     method loopcheck {} {
ac02614803 2007-12-02       aku: 	log write 7 csets {Checking [$self str] for loops /[llength $myitems]}
b42cff97e3 2007-11-30       aku: 
b42cff97e3 2007-11-30       aku: 	if {![struct::set contains [$self successors] $self]} {
b42cff97e3 2007-11-30       aku: 	    return 0
b42cff97e3 2007-11-30       aku: 	}
b42cff97e3 2007-11-30       aku: 	if {[log verbosity?] < 8} { return 1 }
b42cff97e3 2007-11-30       aku: 
b42cff97e3 2007-11-30       aku: 	# Print the detailed successor structure of the self-
b42cff97e3 2007-11-30       aku: 	# referential changeset, if the verbosity of the log is dialed
b42cff97e3 2007-11-30       aku: 	# high enough.
b42cff97e3 2007-11-30       aku: 
b42cff97e3 2007-11-30       aku: 	log write 8 csets [set hdr {Self-referential changeset [$self str] __________________}]
b42cff97e3 2007-11-30       aku: 	array set nmap [$self nextmap]
b42cff97e3 2007-11-30       aku: 	foreach item [lsort -dict [array names nmap]] {
b42cff97e3 2007-11-30       aku: 	    foreach succitem $nmap($item) {
b42cff97e3 2007-11-30       aku: 		set succcs $myitemmap($succitem)
b42cff97e3 2007-11-30       aku: 		set hint [expr {($succcs eq $self)
b42cff97e3 2007-11-30       aku: 				? "LOOP"
b42cff97e3 2007-11-30       aku: 				: "    "}]
b42cff97e3 2007-11-30       aku: 		set i   "<$item [$type itemstr $item]>"
b42cff97e3 2007-11-30       aku: 		set s   "<$succitem [$type itemstr $succitem]>"
b42cff97e3 2007-11-30       aku: 		set scs [$succcs str]
b42cff97e3 2007-11-30       aku: 		log write 8 csets {$hint * $i --> $s --> cs $scs}
b42cff97e3 2007-11-30       aku: 	    }
b42cff97e3 2007-11-30       aku: 	}
b42cff97e3 2007-11-30       aku: 	log write 8 csets [regsub -all {[^ 	]} $hdr {_}]
b42cff97e3 2007-11-30       aku: 	return 1
deab4d035b 2007-11-29       aku:     }
deab4d035b 2007-11-29       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
deab4d035b 2007-11-29       aku: 	# ARGS as sets of items, all subsets of CSET's item set, CSET
deab4d035b 2007-11-29       aku: 	# will be dropped from all databases, in and out of memory,
deab4d035b 2007-11-29       aku: 	# and then destroyed.
0fcfbf7828 2007-11-29       aku: 	#
0fcfbf7828 2007-11-29       aku: 	# Note: The item lists found in args are tagged items. They
0fcfbf7828 2007-11-29       aku: 	# have to have the same type as the changeset, being subsets
0fcfbf7828 2007-11-29       aku: 	# of its items. This is checked in Untag1.
deab4d035b 2007-11-29       aku: 
b42cff97e3 2007-11-30       aku: 	log write 8 csets {OLD: [lsort [$cset items]]}
c14e8f84cd 2007-11-30       aku: 	ValidateFragments $cset $args
b42cff97e3 2007-11-30       aku: 
b42cff97e3 2007-11-30       aku: 	# All checks pass, actually perform the split.
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 {}
deab4d035b 2007-11-29       aku: 	foreach fragmentitems $args {
b42cff97e3 2007-11-30       aku: 	    log write 8 csets {MAKE: [lsort $fragmentitems]}
b42cff97e3 2007-11-30       aku: 
b42cff97e3 2007-11-30       aku: 	    set fragment [$type %AUTO% $project $cstype $cssrc \
b42cff97e3 2007-11-30       aku: 			      [Untag $fragmentitems $cstype]]
b42cff97e3 2007-11-30       aku: 	    lappend newcsets $fragment
b42cff97e3 2007-11-30       aku: 	    $fragment persist
b42cff97e3 2007-11-30       aku: 
0af7a3c8ac 2007-11-30       aku: 	    if {[$fragment loopcheck]} {
b42cff97e3 2007-11-30       aku: 		trouble fatal "[$fragment str] depends on itself"
eabaea870a 2007-11-24       aku: 	    }
b42cff97e3 2007-11-30       aku: 	}
b42cff97e3 2007-11-30       aku: 
b42cff97e3 2007-11-30       aku: 	trouble abort?
59207428e2 2007-11-22       aku: 	return $newcsets
c14e8f84cd 2007-11-30       aku:     }
c14e8f84cd 2007-11-30       aku: 
c14e8f84cd 2007-11-30       aku:     typemethod itemstr {item} {
c14e8f84cd 2007-11-30       aku: 	struct::list assign $item itype iid
c14e8f84cd 2007-11-30       aku: 	return [$itype str $iid]
87cf609021 2007-11-24       aku:     }
87cf609021 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 }
87cf609021 2007-11-24       aku: 
0fcfbf7828 2007-11-29       aku:     proc Untag {taggeditems cstype} {
0fcfbf7828 2007-11-29       aku: 	return [struct::list map $taggeditems [myproc Untag1 $cstype]]
0fcfbf7828 2007-11-29       aku:     }
0fcfbf7828 2007-11-29       aku: 
0fcfbf7828 2007-11-29       aku:     proc Untag1 {cstype theitem} {
0fcfbf7828 2007-11-29       aku: 	struct::list assign $theitem t i
0fcfbf7828 2007-11-29       aku: 	integrity assert {$cstype eq $t} {Item $i's type is '$t', expected '$cstype'}
0fcfbf7828 2007-11-29       aku: 	return $i
0fcfbf7828 2007-11-29       aku:     }
0fcfbf7828 2007-11-29       aku: 
c14e8f84cd 2007-11-30       aku:     proc ValidateFragments {cset fragments} {
c14e8f84cd 2007-11-30       aku: 	# Check the various integrity constraints for the fragments
c14e8f84cd 2007-11-30       aku: 	# specifying how to split the changeset:
c14e8f84cd 2007-11-30       aku: 	#
c14e8f84cd 2007-11-30       aku: 	# * We must have two or more fragments, as splitting a
c14e8f84cd 2007-11-30       aku: 	#   changeset into one makes no sense.
c14e8f84cd 2007-11-30       aku: 	# * No fragment may be empty.
c14e8f84cd 2007-11-30       aku: 	# * All fragments have to be true subsets of the items in the
c14e8f84cd 2007-11-30       aku: 	#   changeset to split. The 'true' is implied because none are
c14e8f84cd 2007-11-30       aku: 	#   allowed to be empty, so each has to be smaller than the
c14e8f84cd 2007-11-30       aku: 	#   total.
c14e8f84cd 2007-11-30       aku: 	# * The union of the fragments has to be the item set of the
c14e8f84cd 2007-11-30       aku: 	#   changeset.
c14e8f84cd 2007-11-30       aku: 	# * The fragment must not overlap, i.e. their pairwise
c14e8f84cd 2007-11-30       aku: 	#   intersections have to be empty.
c14e8f84cd 2007-11-30       aku: 
c14e8f84cd 2007-11-30       aku: 	set cover {}
fbfb531868 2007-12-02       aku: 	foreach fragmentitems $fragments {
c14e8f84cd 2007-11-30       aku: 	    log write 8 csets {NEW: [lsort $fragmentitems]}
c14e8f84cd 2007-11-30       aku: 
c14e8f84cd 2007-11-30       aku: 	    integrity assert {
c14e8f84cd 2007-11-30       aku: 		![struct::set empty $fragmentitems]
c14e8f84cd 2007-11-30       aku: 	    } {changeset fragment is empty}
c14e8f84cd 2007-11-30       aku: 
c14e8f84cd 2007-11-30       aku: 	    integrity assert {
c14e8f84cd 2007-11-30       aku: 		[struct::set subsetof $fragmentitems [$cset items]]
c14e8f84cd 2007-11-30       aku: 	    } {changeset fragment is not a subset}
c14e8f84cd 2007-11-30       aku: 	    struct::set add cover $fragmentitems
c14e8f84cd 2007-11-30       aku: 	}
c14e8f84cd 2007-11-30       aku: 
c14e8f84cd 2007-11-30       aku: 	integrity assert {
c14e8f84cd 2007-11-30       aku: 	    [struct::set equal $cover [$cset items]]
c14e8f84cd 2007-11-30       aku: 	 } {The fragments do not cover the original changeset}
c14e8f84cd 2007-11-30       aku: 
c14e8f84cd 2007-11-30       aku: 	set i 1
fbfb531868 2007-12-02       aku: 	foreach fia $fragments {
fbfb531868 2007-12-02       aku: 	    foreach fib [lrange $fragments $i end] {
c14e8f84cd 2007-11-30       aku: 		integrity assert {
c14e8f84cd 2007-11-30       aku: 		    [struct::set empty [struct::set intersect $fia $fib]]
c14e8f84cd 2007-11-30       aku: 		} {The fragments <$fia> and <$fib> overlap}
c14e8f84cd 2007-11-30       aku: 	    }
c14e8f84cd 2007-11-30       aku: 	    incr i
c14e8f84cd 2007-11-30       aku: 	}
c14e8f84cd 2007-11-30       aku: 
84de38d73f 2007-10-10       aku: 	return
84de38d73f 2007-10-10       aku:     }
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.
c74fe3de3f 2007-11-29       aku:     variable mytype      {} ; # What the changeset is based on
c74fe3de3f 2007-11-29       aku: 			      # (revisions, tags, or branches).
c74fe3de3f 2007-11-29       aku: 			      # Values: See mycstype. Note that we
c74fe3de3f 2007-11-29       aku: 			      # have to keep the names of the helper
c74fe3de3f 2007-11-29       aku: 			      # singletons in sync with the contents
c74fe3de3f 2007-11-29       aku: 			      # of state table 'cstype', and various
c74fe3de3f 2007-11-29       aku: 			      # other places using them hardwired.
c74fe3de3f 2007-11-29       aku:     variable mytypeobj   {} ; # Reference to the container for the
c74fe3de3f 2007-11-29       aku: 			      # type dependent code. Derived from
c74fe3de3f 2007-11-29       aku: 			      # mytype.
94c39d6375 2007-11-14       aku:     variable mysrcid     {} ; # Id of the metadata or symbol the cset
94c39d6375 2007-11-14       aku: 			      # is based on.
deab4d035b 2007-11-29       aku:     variable myitems     {} ; # List of the file level revisions,
0fcfbf7828 2007-11-29       aku: 			      # tags, or branches in the cset, as
0fcfbf7828 2007-11-29       aku: 			      # ids. Not tagged.
deab4d035b 2007-11-29       aku:     variable mytitems    {} ; # As myitems, the tagged form.
0fcfbf7828 2007-11-29       aku:     variable mypremap    {} ; # Dictionary mapping from the items (tagged now)
0fcfbf7828 2007-11-29       aku: 			      # to their predecessors, also tagged. A
0fcfbf7828 2007-11-29       aku: 			      # cache to avoid loading this from the
0fcfbf7828 2007-11-29       aku: 			      # state more than once.
0fcfbf7828 2007-11-29       aku:     variable mynextmap   {} ; # Dictionary mapping from the items (tagged)
0fcfbf7828 2007-11-29       aku: 			      # to their successors (also tagged). A
0fcfbf7828 2007-11-29       aku: 			      # cache to avoid loading this from the
0fcfbf7828 2007-11-29       aku: 			      # state more than 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: 
70d2283564 2007-11-29       aku:     typevariable mycounter        0 ; # Id counter for csets. Last id
70d2283564 2007-11-29       aku: 				      # used.
c74fe3de3f 2007-11-29       aku:     typevariable mycstype -array {} ; # Map cstypes (names) to persistent
c74fe3de3f 2007-11-29       aku: 				      # ids. Note that we have to keep
c74fe3de3f 2007-11-29       aku: 				      # the names in the table 'cstype'
c74fe3de3f 2007-11-29       aku: 				      # in sync with the names of the
c74fe3de3f 2007-11-29       aku: 				      # helper singletons.
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 }]
96b7bfb834 2007-11-16       aku: 	return
96b7bfb834 2007-11-16       aku:     }
96b7bfb834 2007-11-16       aku: 
96167b2a48 2007-11-25       aku:     typemethod num {} { return $mycounter }
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
70d2283564 2007-11-29       aku: 	#         'rev internalsuccessors'.
678765068d 2007-11-27       aku: 
678765068d 2007-11-27       aku: 	foreach {rid children} [array get dependencies] {
678765068d 2007-11-27       aku: 	    foreach child $children {
678765068d 2007-11-27       aku: 		set dkey    [list $rid $child]
678765068d 2007-11-27       aku: 		set start   $pos($rid)
678765068d 2007-11-27       aku: 		set end     $pos($child)
678765068d 2007-11-27       aku: 		set crosses {}
678765068d 2007-11-27       aku: 
678765068d 2007-11-27       aku: 		if {$start > $end} {
678765068d 2007-11-27       aku: 		    while {$end < $start} {
678765068d 2007-11-27       aku: 			lappend crosses $end
678765068d 2007-11-27       aku: 			incr cross($end)
678765068d 2007-11-27       aku: 			incr end
678765068d 2007-11-27       aku: 		    }
678765068d 2007-11-27       aku: 		} else {
678765068d 2007-11-27       aku: 		    while {$start < $end} {
678765068d 2007-11-27       aku: 			lappend crosses $start
678765068d 2007-11-27       aku: 			incr cross($start)
678765068d 2007-11-27       aku: 			incr start
678765068d 2007-11-27       aku: 		    }
08ebab80cd 2007-11-10       aku: 		}
678765068d 2007-11-27       aku: 		set depc($dkey) $crosses
678765068d 2007-11-27       aku: 	    }
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
911d56a8c8 2007-11-27       aku: 	    log write 5 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.
ac02614803 2007-12-02       aku:     # TODO: Replace with call to itemstr (list rev $id)
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
ac02614803 2007-12-02       aku: 		AND   F.fid = R.fid
ac02614803 2007-12-02       aku: 		AND   P.pid = F.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: 
deab4d035b 2007-11-29       aku:     typevariable mychangesets     {} ; # List of all known changesets.
deab4d035b 2007-11-29       aku:     typevariable myitemmap -array {} ; # Map from items (tagged) to
deab4d035b 2007-11-29       aku: 				       # the list of changesets
deab4d035b 2007-11-29       aku: 				       # containing it. Each item can
deab4d035b 2007-11-29       aku: 				       # be used by only one
deab4d035b 2007-11-29       aku: 				       # changeset.
deab4d035b 2007-11-29       aku:     typevariable myidmap   -array {} ; # Map from changeset id to
deab4d035b 2007-11-29       aku: 				       # changeset.
deab4d035b 2007-11-29       aku: 
04d76a9e79 2007-11-29       aku:     typemethod all    {}    { return $mychangesets }
04d76a9e79 2007-11-29       aku:     typemethod of     {cid} { return $myidmap($cid) }
04d76a9e79 2007-11-29       aku:     typemethod ofitem {iid} { return $myitemmap($iid) }
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
27b15b7095 2007-11-29       aku: 
27b15b7095 2007-11-29       aku:     # # ## ### ##### ######## #############
27b15b7095 2007-11-29       aku: }
70d2283564 2007-11-29       aku: 
c14e8f84cd 2007-11-30       aku: ##
c14e8f84cd 2007-11-30       aku: ## NOTE: The successor and predecessor methods defined by the classes
c14e8f84cd 2007-11-30       aku: ##       below are -- bottle necks --. Look for ways to make the SQL
c14e8f84cd 2007-11-30       aku: ##       faster.
c14e8f84cd 2007-11-30       aku: ##
27b15b7095 2007-11-29       aku: 
27b15b7095 2007-11-29       aku: # # ## ### ##### ######## ############# #####################
27b15b7095 2007-11-29       aku: ## Helper singleton. Commands for revision changesets.
27b15b7095 2007-11-29       aku: 
27b15b7095 2007-11-29       aku: snit::type ::vc::fossil::import::cvs::project::rev::rev {
27b15b7095 2007-11-29       aku:     typemethod byrevision {} { return 1 }
27b15b7095 2007-11-29       aku:     typemethod bysymbol   {} { return 0 }
27b15b7095 2007-11-29       aku:     typemethod istag      {} { return 0 }
27b15b7095 2007-11-29       aku:     typemethod isbranch   {} { return 0 }
27b15b7095 2007-11-29       aku: 
b42cff97e3 2007-11-30       aku:     typemethod str {revision} {
b42cff97e3 2007-11-30       aku: 	struct::list assign [state run {
b42cff97e3 2007-11-30       aku: 	    SELECT R.rev, F.name, P.name
b42cff97e3 2007-11-30       aku: 	    FROM   revision R, file F, project P
b42cff97e3 2007-11-30       aku: 	    WHERE  R.rid = $revision
b42cff97e3 2007-11-30       aku: 	    AND    F.fid = R.fid
b42cff97e3 2007-11-30       aku: 	    AND    P.pid = F.pid
b42cff97e3 2007-11-30       aku: 	}] revnr fname pname
b42cff97e3 2007-11-30       aku: 	return "$pname/${revnr}::$fname"
b42cff97e3 2007-11-30       aku:     }
c74fe3de3f 2007-11-29       aku: 
27b15b7095 2007-11-29       aku:     # result = list (mintime, maxtime)
27b15b7095 2007-11-29       aku:     typemethod timerange {items} {
c74fe3de3f 2007-11-29       aku: 	set theset ('[join $items {','}]')
c74fe3de3f 2007-11-29       aku: 	return [state run "
c74fe3de3f 2007-11-29       aku: 	    SELECT MIN(R.date), MAX(R.date)
c74fe3de3f 2007-11-29       aku: 	    FROM revision R
c74fe3de3f 2007-11-29       aku: 	    WHERE R.rid IN $theset
c74fe3de3f 2007-11-29       aku: 	"]
27b15b7095 2007-11-29       aku:     }
27b15b7095 2007-11-29       aku: 
27b15b7095 2007-11-29       aku:     # var(dv) = dict (revision -> list (revision))
27b15b7095 2007-11-29       aku:     typemethod internalsuccessors {dv revisions} {
70d2283564 2007-11-29       aku: 	upvar 1 $dv dependencies
70d2283564 2007-11-29       aku: 	set theset ('[join $revisions {','}]')
70d2283564 2007-11-29       aku: 
70d2283564 2007-11-29       aku: 	# See 'successors' below for the main explanation of
70d2283564 2007-11-29       aku: 	# the various cases. This piece is special in that it
70d2283564 2007-11-29       aku: 	# restricts the successors we look for to the same set of
70d2283564 2007-11-29       aku: 	# revisions we start from. Sensible as we are looking for
70d2283564 2007-11-29       aku: 	# changeset internal dependencies.
70d2283564 2007-11-29       aku: 
70d2283564 2007-11-29       aku: 	array set dep {}
70d2283564 2007-11-29       aku: 
70d2283564 2007-11-29       aku: 	foreach {rid child} [state run "
70d2283564 2007-11-29       aku:    -- (1) Primary child
70d2283564 2007-11-29       aku: 	    SELECT R.rid, R.child
70d2283564 2007-11-29       aku: 	    FROM   revision R
70d2283564 2007-11-29       aku: 	    WHERE  R.rid   IN $theset     -- Restrict to revisions of interest
70d2283564 2007-11-29       aku: 	    AND    R.child IS NOT NULL    -- Has primary child
70d2283564 2007-11-29       aku: 	    AND    R.child IN $theset     -- Which is also of interest
70d2283564 2007-11-29       aku:     UNION
70d2283564 2007-11-29       aku:     -- (2) Secondary (branch) children
70d2283564 2007-11-29       aku: 	    SELECT R.rid, B.brid
70d2283564 2007-11-29       aku: 	    FROM   revision R, revisionbranchchildren B
70d2283564 2007-11-29       aku: 	    WHERE  R.rid   IN $theset     -- Restrict to revisions of interest
70d2283564 2007-11-29       aku: 	    AND    R.rid = B.rid          -- Select subset of branch children
70d2283564 2007-11-29       aku: 	    AND    B.brid IN $theset      -- Which is also of interest
70d2283564 2007-11-29       aku:     UNION
70d2283564 2007-11-29       aku:     -- (4) Child of trunk root successor of last NTDB on trunk.
70d2283564 2007-11-29       aku: 	    SELECT R.rid, RA.child
70d2283564 2007-11-29       aku: 	    FROM revision R, revision RA
70d2283564 2007-11-29       aku: 	    WHERE R.rid   IN $theset      -- Restrict to revisions of interest
70d2283564 2007-11-29       aku: 	    AND   R.isdefault             -- Restrict to NTDB
70d2283564 2007-11-29       aku: 	    AND   R.dbchild IS NOT NULL   -- and last NTDB belonging to trunk
70d2283564 2007-11-29       aku: 	    AND   RA.rid = R.dbchild      -- Go directly to trunk root
70d2283564 2007-11-29       aku: 	    AND   RA.child IS NOT NULL    -- Has primary child.
70d2283564 2007-11-29       aku:             AND   RA.child IN $theset     -- Which is also of interest
70d2283564 2007-11-29       aku: 	"] {
70d2283564 2007-11-29       aku: 	    # Consider moving this to the integrity module.
70d2283564 2007-11-29       aku: 	    integrity assert {$rid != $child} {Revision $rid depends on itself.}
70d2283564 2007-11-29       aku: 	    lappend dependencies($rid) $child
70d2283564 2007-11-29       aku: 	    set dep($rid,$child) .
70d2283564 2007-11-29       aku: 	}
70d2283564 2007-11-29       aku: 
70d2283564 2007-11-29       aku: 	# The sql statements above looks only for direct dependencies
70d2283564 2007-11-29       aku: 	# between revision in the changeset. However due to the
70d2283564 2007-11-29       aku: 	# vagaries of meta data it is possible for two revisions of
70d2283564 2007-11-29       aku: 	# the same file to end up in the same changeset, without a
70d2283564 2007-11-29       aku: 	# direct dependency between them. However we know that there
70d2283564 2007-11-29       aku: 	# has to be a an indirect dependency, be it through primary
70d2283564 2007-11-29       aku: 	# children, branch children, or a combination thereof.
70d2283564 2007-11-29       aku: 
70d2283564 2007-11-29       aku: 	# We now fill in these pseudo-dependencies, if no such
70d2283564 2007-11-29       aku: 	# dependency exists already. The direction of the dependency
70d2283564 2007-11-29       aku: 	# is actually irrelevant for this.
70d2283564 2007-11-29       aku: 
70d2283564 2007-11-29       aku: 	# NOTE: This is different from cvs2svn. Our spiritual ancestor
70d2283564 2007-11-29       aku: 	# does not use such pseudo-dependencies, however it uses a
70d2283564 2007-11-29       aku: 	# COMMIT_THRESHOLD, a time interval commits should fall. This
70d2283564 2007-11-29       aku: 	# will greatly reduces the risk of getting far separated
70d2283564 2007-11-29       aku: 	# revisions of the same file into one changeset.
70d2283564 2007-11-29       aku: 
70d2283564 2007-11-29       aku: 	# We allow revisions to be far apart in time in the same
fbfb531868 2007-12-02       aku: 	# changeset, but in turn need the pseudo-dependencies to
fbfb531868 2007-12-02       aku: 	# handle this.
70d2283564 2007-11-29       aku: 
70d2283564 2007-11-29       aku: 	array set fids {}
70d2283564 2007-11-29       aku: 	foreach {rid fid} [state run "
fbfb531868 2007-12-02       aku: 	    SELECT R.rid, R.fid
fbfb531868 2007-12-02       aku:             FROM   revision R
fbfb531868 2007-12-02       aku:             WHERE  R.rid IN $theset
70d2283564 2007-11-29       aku: 	"] { lappend fids($fid) $rid }
70d2283564 2007-11-29       aku: 
70d2283564 2007-11-29       aku: 	foreach {fid rids} [array get fids] {
70d2283564 2007-11-29       aku: 	    if {[llength $rids] < 2} continue
70d2283564 2007-11-29       aku: 	    foreach a $rids {
70d2283564 2007-11-29       aku: 		foreach b $rids {
70d2283564 2007-11-29       aku: 		    if {$a == $b} continue
70d2283564 2007-11-29       aku: 		    if {[info exists dep($a,$b)]} continue
70d2283564 2007-11-29       aku: 		    if {[info exists dep($b,$a)]} continue
70d2283564 2007-11-29       aku: 		    lappend dependencies($a) $b
70d2283564 2007-11-29       aku: 		    set dep($a,$b) .
70d2283564 2007-11-29       aku: 		    set dep($b,$a) .
70d2283564 2007-11-29       aku: 		}
70d2283564 2007-11-29       aku: 	    }
70d2283564 2007-11-29       aku: 	}
70d2283564 2007-11-29       aku: 	return
27b15b7095 2007-11-29       aku:     }
27b15b7095 2007-11-29       aku: 
27b15b7095 2007-11-29       aku:     # var(dv) = dict (item -> list (item)), item  = list (type id)
27b15b7095 2007-11-29       aku:     typemethod successors {dv revisions} {
70d2283564 2007-11-29       aku: 	upvar 1 $dv dependencies
70d2283564 2007-11-29       aku: 	set theset ('[join $revisions {','}]')
70d2283564 2007-11-29       aku: 
70d2283564 2007-11-29       aku: 	# The following cases specify when a revision S is a successor
70d2283564 2007-11-29       aku: 	# of a revision R. Each of the cases translates into one of
70d2283564 2007-11-29       aku: 	# the branches of the SQL UNION coming below.
70d2283564 2007-11-29       aku: 	#
70d2283564 2007-11-29       aku: 	# (1) S can be a primary child of R, i.e. in the same LOD. R
70d2283564 2007-11-29       aku: 	#     references S directly. R.child = S(.rid), if it exists.
70d2283564 2007-11-29       aku: 	#
70d2283564 2007-11-29       aku: 	# (2) S can be a secondary, i.e. branch, child of R. Here the
70d2283564 2007-11-29       aku: 	#     link is made through the helper table
70d2283564 2007-11-29       aku: 	#     REVISIONBRANCHCHILDREN. R.rid -> RBC.rid, RBC.brid =
70d2283564 2007-11-29       aku: 	#     S(.rid)
70d2283564 2007-11-29       aku: 	#
70d2283564 2007-11-29       aku: 	# (3) Originally this use case defined the root of a detached
70d2283564 2007-11-29       aku: 	#     NTDB as the successor of the trunk root. This leads to a
70d2283564 2007-11-29       aku: 	#     bad tangle later on. With a detached NTDB the original
70d2283564 2007-11-29       aku: 	#     trunk root revision was removed as irrelevant, allowing
70d2283564 2007-11-29       aku: 	#     the nominal root to be later in time than the NTDB
70d2283564 2007-11-29       aku: 	#     root. Now setting this dependency will be backward in
70d2283564 2007-11-29       aku: 	#     time. REMOVED.
70d2283564 2007-11-29       aku: 	#
70d2283564 2007-11-29       aku: 	# (4) If R is the last of the NTDB revisions which belong to
70d2283564 2007-11-29       aku: 	#     the trunk, then the primary child of the trunk root (the
70d2283564 2007-11-29       aku: 	#     '1.2' revision) is a successor, if it exists.
70d2283564 2007-11-29       aku: 
70d2283564 2007-11-29       aku: 	# Note that the branches spawned from the revisions, and the
70d2283564 2007-11-29       aku: 	# tags associated with them are successors as well.
70d2283564 2007-11-29       aku: 
70d2283564 2007-11-29       aku: 	foreach {rid child} [state run "
70d2283564 2007-11-29       aku:    -- (1) Primary child
70d2283564 2007-11-29       aku: 	    SELECT R.rid, R.child
70d2283564 2007-11-29       aku: 	    FROM   revision R
70d2283564 2007-11-29       aku: 	    WHERE  R.rid   IN $theset     -- Restrict to revisions of interest
70d2283564 2007-11-29       aku: 	    AND    R.child IS NOT NULL    -- Has primary child
70d2283564 2007-11-29       aku:     UNION
70d2283564 2007-11-29       aku:     -- (2) Secondary (branch) children
70d2283564 2007-11-29       aku: 	    SELECT R.rid, B.brid
70d2283564 2007-11-29       aku: 	    FROM   revision R, revisionbranchchildren B
70d2283564 2007-11-29       aku: 	    WHERE  R.rid   IN $theset     -- Restrict to revisions of interest
70d2283564 2007-11-29       aku: 	    AND    R.rid = B.rid          -- Select subset of branch children
70d2283564 2007-11-29       aku:     UNION
70d2283564 2007-11-29       aku:     -- (4) Child of trunk root successor of last NTDB on trunk.
70d2283564 2007-11-29       aku: 	    SELECT R.rid, RA.child
70d2283564 2007-11-29       aku: 	    FROM revision R, revision RA
70d2283564 2007-11-29       aku: 	    WHERE R.rid   IN $theset      -- Restrict to revisions of interest
70d2283564 2007-11-29       aku: 	    AND   R.isdefault             -- Restrict to NTDB
70d2283564 2007-11-29       aku: 	    AND   R.dbchild IS NOT NULL   -- and last NTDB belonging to trunk
70d2283564 2007-11-29       aku: 	    AND   RA.rid = R.dbchild      -- Go directly to trunk root
70d2283564 2007-11-29       aku: 	    AND   RA.child IS NOT NULL    -- Has primary child.
70d2283564 2007-11-29       aku: 	"] {
70d2283564 2007-11-29       aku: 	    # Consider moving this to the integrity module.
70d2283564 2007-11-29       aku: 	    integrity assert {$rid != $child} {Revision $rid depends on itself.}
70d2283564 2007-11-29       aku: 	    lappend dependencies([list rev $rid]) [list rev $child]
70d2283564 2007-11-29       aku: 	}
70d2283564 2007-11-29       aku: 	foreach {rid child} [state run "
70d2283564 2007-11-29       aku: 	    SELECT R.rid, T.tid
70d2283564 2007-11-29       aku: 	    FROM   revision R, tag T
70d2283564 2007-11-29       aku: 	    WHERE  R.rid in $theset
70d2283564 2007-11-29       aku: 	    AND    T.rev = R.rid
70d2283564 2007-11-29       aku: 	"] {
70d2283564 2007-11-29       aku: 	    lappend dependencies([list rev $rid]) [list sym::tag $child]
70d2283564 2007-11-29       aku: 	}
70d2283564 2007-11-29       aku: 	foreach {rid child} [state run "
70d2283564 2007-11-29       aku: 	    SELECT R.rid, B.bid
70d2283564 2007-11-29       aku: 	    FROM   revision R, branch B
70d2283564 2007-11-29       aku: 	    WHERE  R.rid in $theset
70d2283564 2007-11-29       aku: 	    AND    B.root = R.rid
70d2283564 2007-11-29       aku: 	"] {
70d2283564 2007-11-29       aku: 	    lappend dependencies([list rev $rid]) [list sym::branch $child]
70d2283564 2007-11-29       aku: 	}
70d2283564 2007-11-29       aku: 	return
27b15b7095 2007-11-29       aku:     }
27b15b7095 2007-11-29       aku: 
27b15b7095 2007-11-29       aku:     # var(dv) = dict (item -> list (item)), item  = list (type id)
27b15b7095 2007-11-29       aku:     typemethod predecessors {dv revisions} {
70d2283564 2007-11-29       aku: 	upvar 1 $dv dependencies
70d2283564 2007-11-29       aku: 	set theset ('[join $revisions {','}]')
70d2283564 2007-11-29       aku: 
70d2283564 2007-11-29       aku: 	# The following cases specify when a revision P is a
70d2283564 2007-11-29       aku: 	# predecessor of a revision R. Each of the cases translates
70d2283564 2007-11-29       aku: 	# into one of the branches of the SQL UNION coming below.
70d2283564 2007-11-29       aku: 	#
70d2283564 2007-11-29       aku: 	# (1) The immediate parent R.parent of R is a predecessor of
70d2283564 2007-11-29       aku: 	#     R. NOTE: This is true for R either primary or secondary
70d2283564 2007-11-29       aku: 	#     child of P. It not necessary to distinguish the two
70d2283564 2007-11-29       aku: 	#     cases, in contrast to the code retrieving the successor
70d2283564 2007-11-29       aku: 	#     information.
70d2283564 2007-11-29       aku: 	#
70d2283564 2007-11-29       aku: 	# (2) The complement of successor case (3). The trunk root is
70d2283564 2007-11-29       aku: 	#     a predecessor of a NTDB root. REMOVED. See 'successors'
70d2283564 2007-11-29       aku: 	#     for the explanation.
70d2283564 2007-11-29       aku: 	#
70d2283564 2007-11-29       aku: 	# (3) The complement of successor case (4). The last NTDB
70d2283564 2007-11-29       aku: 	#     revision belonging to the trunk is a predecessor of the
70d2283564 2007-11-29       aku: 	#     primary child of the trunk root (The '1.2' revision).
70d2283564 2007-11-29       aku: 
70d2283564 2007-11-29       aku: 	foreach {rid parent} [state run "
70d2283564 2007-11-29       aku:    -- (1) Primary parent, can be in different LOD for first in a branch
70d2283564 2007-11-29       aku: 	    SELECT R.rid, R.parent
70d2283564 2007-11-29       aku: 	    FROM   revision R
70d2283564 2007-11-29       aku: 	    WHERE  R.rid   IN $theset     -- Restrict to revisions of interest
70d2283564 2007-11-29       aku: 	    AND    R.parent IS NOT NULL   -- Has primary parent
70d2283564 2007-11-29       aku:     UNION
70d2283564 2007-11-29       aku:     -- (3) Last NTDB on trunk is predecessor of child of trunk root
70d2283564 2007-11-29       aku: 	    SELECT R.rid, RA.dbparent
70d2283564 2007-11-29       aku: 	    FROM   revision R, revision RA
70d2283564 2007-11-29       aku: 	    WHERE  R.rid IN $theset         -- Restrict to revisions of interest
70d2283564 2007-11-29       aku: 	    AND    NOT R.isdefault          -- not on NTDB
70d2283564 2007-11-29       aku: 	    AND    R.parent IS NOT NULL     -- which are not root
70d2283564 2007-11-29       aku: 	    AND    RA.rid = R.parent        -- go to their parent
70d2283564 2007-11-29       aku: 	    AND    RA.dbparent IS NOT NULL  -- which has to refer to NTDB's root
70d2283564 2007-11-29       aku: 	"] {
70d2283564 2007-11-29       aku: 	    # Consider moving this to the integrity module.
70d2283564 2007-11-29       aku: 	    integrity assert {$rid != $parent} {Revision $rid depends on itself.}
70d2283564 2007-11-29       aku: 	    lappend dependencies([list rev $rid]) [list rev $parent]
70d2283564 2007-11-29       aku: 	}
70d2283564 2007-11-29       aku: 
70d2283564 2007-11-29       aku: 	# The revisions which are the first on a branch have that
70d2283564 2007-11-29       aku: 	# branch as their predecessor. Note that revisions cannot be
70d2283564 2007-11-29       aku: 	# on tags in the same manner, so tags cannot be predecessors
70d2283564 2007-11-29       aku: 	# of revisions. This complements that they have no successors
70d2283564 2007-11-29       aku: 	# (See sym::tag/successors).
70d2283564 2007-11-29       aku: 
70d2283564 2007-11-29       aku: 	foreach {rid parent} [state run "
fbfb531868 2007-12-02       aku: 	    SELECT R.rid, B.bid
70d2283564 2007-11-29       aku: 	    FROM   revision R, branch B
70d2283564 2007-11-29       aku: 	    WHERE  R.rid IN $theset
70d2283564 2007-11-29       aku: 	    AND    B.first = R.rid
70d2283564 2007-11-29       aku: 	"] {
70d2283564 2007-11-29       aku: 	    lappend dependencies([list rev $rid]) [list sym::branch $parent]
70d2283564 2007-11-29       aku: 	}
70d2283564 2007-11-29       aku: 	return
fbfb531868 2007-12-02       aku:     }
9c57055025 2007-12-02       aku: 
9c57055025 2007-12-02       aku:     # result = list (changeset-id)
9c57055025 2007-12-02       aku:     typemethod cs_successors {revisions} {
9c57055025 2007-12-02       aku:         # This is a variant of 'successors' which maps the low-level
9c57055025 2007-12-02       aku:         # data directly to the associated changesets. I.e. instead
9c57055025 2007-12-02       aku:         # millions of dependency pairs (in extreme cases (Example: Tcl
9c57055025 2007-12-02       aku:         # CVS)) we return a very short and much more manageable list
9c57055025 2007-12-02       aku:         # of changesets.
9c57055025 2007-12-02       aku: 
9c57055025 2007-12-02       aku: 	set theset ('[join $revisions {','}]')
9c57055025 2007-12-02       aku: 	return [state run "
9c57055025 2007-12-02       aku: 	    SELECT C.cid
9c57055025 2007-12-02       aku: 	    FROM   revision R, csitem CI, changeset C
9c57055025 2007-12-02       aku: 	    WHERE  R.rid   IN $theset     -- Restrict to revisions of interest
9c57055025 2007-12-02       aku: 	    AND    R.child IS NOT NULL    -- Has primary child
f7cca3f082 2007-12-02       aku:             AND    CI.iid = R.child
9c57055025 2007-12-02       aku:             AND    C.cid = CI.cid
9c57055025 2007-12-02       aku:             AND    C.type = 0
9c57055025 2007-12-02       aku:     UNION
9c57055025 2007-12-02       aku: 	    SELECT C.cid
9c57055025 2007-12-02       aku: 	    FROM   revision R, revisionbranchchildren B, csitem CI, changeset C
9c57055025 2007-12-02       aku: 	    WHERE  R.rid   IN $theset     -- Restrict to revisions of interest
9c57055025 2007-12-02       aku: 	    AND    R.rid = B.rid          -- Select subset of branch children
f7cca3f082 2007-12-02       aku:             AND    CI.iid = B.brid
9c57055025 2007-12-02       aku:             AND    C.cid = CI.cid
9c57055025 2007-12-02       aku:             AND    C.type = 0
9c57055025 2007-12-02       aku:     UNION
9c57055025 2007-12-02       aku: 	    SELECT C.cid
9c57055025 2007-12-02       aku: 	    FROM   revision R, revision RA, csitem CI, changeset C
9c57055025 2007-12-02       aku: 	    WHERE  R.rid   IN $theset      -- Restrict to revisions of interest
9c57055025 2007-12-02       aku: 	    AND    R.isdefault             -- Restrict to NTDB
9c57055025 2007-12-02       aku: 	    AND    R.dbchild IS NOT NULL   -- and last NTDB belonging to trunk
9c57055025 2007-12-02       aku: 	    AND    RA.rid = R.dbchild      -- Go directly to trunk root
9c57055025 2007-12-02       aku: 	    AND    RA.child IS NOT NULL    -- Has primary child.
f7cca3f082 2007-12-02       aku:             AND    CI.iid = RA.child
9c57055025 2007-12-02       aku:             AND    C.cid = CI.cid
9c57055025 2007-12-02       aku:             AND    C.type = 0
9c57055025 2007-12-02       aku:     UNION
9c57055025 2007-12-02       aku: 	    SELECT C.cid
9c57055025 2007-12-02       aku: 	    FROM   revision R, tag T, csitem CI, changeset C
9c57055025 2007-12-02       aku: 	    WHERE  R.rid in $theset
9c57055025 2007-12-02       aku: 	    AND    T.rev = R.rid
9c57055025 2007-12-02       aku:             AND    CI.iid = T.tid
9c57055025 2007-12-02       aku:             AND    C.cid = CI.cid
9c57055025 2007-12-02       aku:             AND    C.type = 1
9c57055025 2007-12-02       aku:     UNION
9c57055025 2007-12-02       aku: 	    SELECT C.cid
9c57055025 2007-12-02       aku: 	    FROM   revision R, branch B, csitem CI, changeset C
9c57055025 2007-12-02       aku: 	    WHERE  R.rid in $theset
9c57055025 2007-12-02       aku: 	    AND    B.root = R.rid
9c57055025 2007-12-02       aku:             AND    CI.iid = B.bid
9c57055025 2007-12-02       aku:             AND    C.cid = CI.cid
9c57055025 2007-12-02       aku:             AND    C.type = 2
9c57055025 2007-12-02       aku: 	"]
27b15b7095 2007-11-29       aku:     }
27b15b7095 2007-11-29       aku: }
27b15b7095 2007-11-29       aku: 
27b15b7095 2007-11-29       aku: # # ## ### ##### ######## ############# #####################
27b15b7095 2007-11-29       aku: ## Helper singleton. Commands for tag symbol changesets.
27b15b7095 2007-11-29       aku: 
27b15b7095 2007-11-29       aku: snit::type ::vc::fossil::import::cvs::project::rev::sym::tag {
27b15b7095 2007-11-29       aku:     typemethod byrevision {} { return 0 }
27b15b7095 2007-11-29       aku:     typemethod bysymbol   {} { return 1 }
27b15b7095 2007-11-29       aku:     typemethod istag      {} { return 1 }
27b15b7095 2007-11-29       aku:     typemethod isbranch   {} { return 0 }
27b15b7095 2007-11-29       aku: 
b42cff97e3 2007-11-30       aku:     typemethod str {tag} {
b42cff97e3 2007-11-30       aku: 	struct::list assign [state run {
b42cff97e3 2007-11-30       aku: 	    SELECT S.name, F.name, P.name
b42cff97e3 2007-11-30       aku: 	    FROM   tag T, symbol S, file F, project P
b42cff97e3 2007-11-30       aku: 	    WHERE  T.tid = $tag
b42cff97e3 2007-11-30       aku: 	    AND    F.fid = T.fid
b42cff97e3 2007-11-30       aku: 	    AND    P.pid = F.pid
b42cff97e3 2007-11-30       aku: 	    AND    S.sid = T.sid
b42cff97e3 2007-11-30       aku: 	}] sname fname pname
b42cff97e3 2007-11-30       aku: 	return "$pname/T'${sname}'::$fname"
b42cff97e3 2007-11-30       aku:     }
b42cff97e3 2007-11-30       aku: 
27b15b7095 2007-11-29       aku:     # result = list (mintime, maxtime)
27b15b7095 2007-11-29       aku:     typemethod timerange {tags} {
b1666f8ff4 2007-11-29       aku: 	# The range is defined as the range of the revisions the tags
b1666f8ff4 2007-11-29       aku: 	# are attached to.
b1666f8ff4 2007-11-29       aku: 
b1666f8ff4 2007-11-29       aku: 	set theset ('[join $tags {','}]')
b1666f8ff4 2007-11-29       aku: 	return [state run "
b1666f8ff4 2007-11-29       aku: 	    SELECT MIN(R.date), MAX(R.date)
fbfb531868 2007-12-02       aku: 	    FROM   tag T, revision R
fbfb531868 2007-12-02       aku: 	    WHERE  T.tid IN $theset
fbfb531868 2007-12-02       aku:             AND    R.rid = T.rev
b1666f8ff4 2007-11-29       aku: 	"]
27b15b7095 2007-11-29       aku:     }
27b15b7095 2007-11-29       aku: 
27b15b7095 2007-11-29       aku:     # var(dv) = dict (item -> list (item)), item  = list (type id)
27b15b7095 2007-11-29       aku:     typemethod successors {dv tags} {
b1666f8ff4 2007-11-29       aku: 	# Tags have no successors.
b1666f8ff4 2007-11-29       aku: 	return
27b15b7095 2007-11-29       aku:     }
27b15b7095 2007-11-29       aku: 
27b15b7095 2007-11-29       aku:     # var(dv) = dict (item -> list (item)), item  = list (type id)
27b15b7095 2007-11-29       aku:     typemethod predecessors {dv tags} {
712010580a 2007-12-02       aku: 	upvar 1 $dv dependencies
b1666f8ff4 2007-11-29       aku: 	# The predecessors of a tag are all the revisions the tags are
b1666f8ff4 2007-11-29       aku: 	# attached to, as well as all the branches or tags which are
b1666f8ff4 2007-11-29       aku: 	# their prefered parents.
b1666f8ff4 2007-11-29       aku: 
b1666f8ff4 2007-11-29       aku: 	set theset ('[join $tags {','}]')
b1666f8ff4 2007-11-29       aku: 	foreach {tid parent} [state run "
b1666f8ff4 2007-11-29       aku: 	    SELECT T.tid, R.rid
fbfb531868 2007-12-02       aku: 	    FROM   tag T, revision R
b1666f8ff4 2007-11-29       aku: 	    WHERE  T.tid IN $theset
b1666f8ff4 2007-11-29       aku: 	    AND    T.rev = R.rid
b1666f8ff4 2007-11-29       aku: 	"] {
b1666f8ff4 2007-11-29       aku: 	    lappend dependencies([list sym::tag $tid]) [list rev $parent]
b1666f8ff4 2007-11-29       aku: 	}
b1666f8ff4 2007-11-29       aku: 
b1666f8ff4 2007-11-29       aku: 	foreach {tid parent} [state run "
b1666f8ff4 2007-11-29       aku: 	    SELECT T.tid, B.bid
fbfb531868 2007-12-02       aku: 	    FROM   tag T, preferedparent P, branch B
b1666f8ff4 2007-11-29       aku: 	    WHERE  T.tid IN $theset
b1666f8ff4 2007-11-29       aku: 	    AND    T.sid = P.sid
b1666f8ff4 2007-11-29       aku: 	    AND    P.pid = B.sid
b1666f8ff4 2007-11-29       aku: 	"] {
b1666f8ff4 2007-11-29       aku: 	    lappend dependencies([list sym::tag $tid]) [list sym::branch $parent]
b1666f8ff4 2007-11-29       aku: 	}
b1666f8ff4 2007-11-29       aku: 
b1666f8ff4 2007-11-29       aku: 	foreach {tid parent} [state run "
b1666f8ff4 2007-11-29       aku: 	    SELECT T.tid, TX.tid
fbfb531868 2007-12-02       aku: 	    FROM   tag T, preferedparent P, tag TX
b1666f8ff4 2007-11-29       aku: 	    WHERE  T.tid IN $theset
b1666f8ff4 2007-11-29       aku: 	    AND    T.sid = P.sid
b1666f8ff4 2007-11-29       aku: 	    AND    P.pid = TX.sid
b1666f8ff4 2007-11-29       aku: 	"] {
b1666f8ff4 2007-11-29       aku: 	    lappend dependencies([list sym::tag $tid]) [list sym::tag $parent]
b1666f8ff4 2007-11-29       aku: 	}
9c57055025 2007-12-02       aku: 	return
9c57055025 2007-12-02       aku:     }
9c57055025 2007-12-02       aku: 
9c57055025 2007-12-02       aku:     # result = list (changeset-id)
9c57055025 2007-12-02       aku:     typemethod cs_successors {tags} {
9c57055025 2007-12-02       aku: 	# Tags have no successors.
b1666f8ff4 2007-11-29       aku: 	return
27b15b7095 2007-11-29       aku:     }
27b15b7095 2007-11-29       aku: }
27b15b7095 2007-11-29       aku: 
27b15b7095 2007-11-29       aku: # # ## ### ##### ######## ############# #####################
27b15b7095 2007-11-29       aku: ## Helper singleton. Commands for branch symbol changesets.
27b15b7095 2007-11-29       aku: 
27b15b7095 2007-11-29       aku: snit::type ::vc::fossil::import::cvs::project::rev::sym::branch {
27b15b7095 2007-11-29       aku:     typemethod byrevision {} { return 0 }
27b15b7095 2007-11-29       aku:     typemethod bysymbol   {} { return 1 }
27b15b7095 2007-11-29       aku:     typemethod istag      {} { return 0 }
27b15b7095 2007-11-29       aku:     typemethod isbranch   {} { return 1 }
27b15b7095 2007-11-29       aku: 
b42cff97e3 2007-11-30       aku:     typemethod str {branch} {
b42cff97e3 2007-11-30       aku: 	struct::list assign [state run {
b42cff97e3 2007-11-30       aku: 	    SELECT S.name, F.name, P.name
b42cff97e3 2007-11-30       aku: 	    FROM   branch B, symbol S, file F, project P
b42cff97e3 2007-11-30       aku: 	    WHERE  B.bid = $branch
b42cff97e3 2007-11-30       aku: 	    AND    F.fid = B.fid
b42cff97e3 2007-11-30       aku: 	    AND    P.pid = F.pid
b42cff97e3 2007-11-30       aku: 	    AND    S.sid = B.sid
b42cff97e3 2007-11-30       aku: 	}] sname fname pname
b42cff97e3 2007-11-30       aku: 	return "$pname/B'${sname}'::$fname"
b42cff97e3 2007-11-30       aku:     }
b42cff97e3 2007-11-30       aku: 
27b15b7095 2007-11-29       aku:     # result = list (mintime, maxtime)
27b15b7095 2007-11-29       aku:     typemethod timerange {branches} {
b1666f8ff4 2007-11-29       aku: 	# The range of a branch is defined as the range of the
b1666f8ff4 2007-11-29       aku: 	# revisions the branches are spawned by. NOTE however that the
b1666f8ff4 2007-11-29       aku: 	# branches associated with a detached NTDB will have no root
b1666f8ff4 2007-11-29       aku: 	# spawning them, hence they have no real timerange any
b1666f8ff4 2007-11-29       aku: 	# longer. By using 0 we put them in front of everything else,
b1666f8ff4 2007-11-29       aku: 	# as they logically are.
b1666f8ff4 2007-11-29       aku: 
b1666f8ff4 2007-11-29       aku: 	set theset ('[join $branches {','}]')
b1666f8ff4 2007-11-29       aku: 	return [state run "
b1666f8ff4 2007-11-29       aku: 	    SELECT IFNULL(MIN(R.date),0), IFNULL(MAX(R.date),0)
fbfb531868 2007-12-02       aku: 	    FROM  branch B, revision R
b1666f8ff4 2007-11-29       aku: 	    WHERE B.bid IN $theset
b1666f8ff4 2007-11-29       aku:             AND   R.rid = B.root
b1666f8ff4 2007-11-29       aku: 	"]
27b15b7095 2007-11-29       aku:     }
27b15b7095 2007-11-29       aku: 
27b15b7095 2007-11-29       aku:     # var(dv) = dict (item -> list (item)), item  = list (type id)
27b15b7095 2007-11-29       aku:     typemethod successors {dv branches} {
712010580a 2007-12-02       aku: 	upvar 1 $dv dependencies
b1666f8ff4 2007-11-29       aku: 	# The first revision committed on a branch, and all branches
b1666f8ff4 2007-11-29       aku: 	# and tags which have it as their prefered parent are the
b1666f8ff4 2007-11-29       aku: 	# successors of a branch.
b1666f8ff4 2007-11-29       aku: 
b1666f8ff4 2007-11-29       aku: 	set theset ('[join $branches {','}]')
b1666f8ff4 2007-11-29       aku: 	foreach {bid child} [state run "
b1666f8ff4 2007-11-29       aku: 	    SELECT B.bid, R.rid
fbfb531868 2007-12-02       aku: 	    FROM   branch B, revision R
b1666f8ff4 2007-11-29       aku: 	    WHERE  B.bid IN $theset
b1666f8ff4 2007-11-29       aku: 	    AND    B.first = R.rid
b1666f8ff4 2007-11-29       aku: 	"] {
b1666f8ff4 2007-11-29       aku: 	    lappend dependencies([list sym::tag $bid]) [list rev $child]
b1666f8ff4 2007-11-29       aku: 	}
b1666f8ff4 2007-11-29       aku: 	foreach {bid child} [state run "
b1666f8ff4 2007-11-29       aku: 	    SELECT B.bid, BX.bid
fbfb531868 2007-12-02       aku: 	    FROM   branch B, preferedparent P, branch BX
b1666f8ff4 2007-11-29       aku: 	    WHERE  B.bid IN $theset
b1666f8ff4 2007-11-29       aku: 	    AND    B.sid = P.pid
b1666f8ff4 2007-11-29       aku: 	    AND    BX.sid = P.sid
b1666f8ff4 2007-11-29       aku: 	"] {
b1666f8ff4 2007-11-29       aku: 	    lappend dependencies([list sym::tag $bid]) [list sym::branch $child]
b1666f8ff4 2007-11-29       aku: 	}
b1666f8ff4 2007-11-29       aku: 	foreach {bid child} [state run "
b1666f8ff4 2007-11-29       aku: 	    SELECT B.bid, T.tid
fbfb531868 2007-12-02       aku: 	    FROM   branch B, preferedparent P, tag T
b1666f8ff4 2007-11-29       aku: 	    WHERE  B.bid IN $theset
b1666f8ff4 2007-11-29       aku: 	    AND    B.sid = P.pid
b1666f8ff4 2007-11-29       aku: 	    AND    T.sid = P.sid
b1666f8ff4 2007-11-29       aku: 	"] {
b1666f8ff4 2007-11-29       aku: 	    lappend dependencies([list sym::tag $bid]) [list sym::tag $child]
b1666f8ff4 2007-11-29       aku: 	}
b1666f8ff4 2007-11-29       aku: 	return
27b15b7095 2007-11-29       aku:     }
27b15b7095 2007-11-29       aku: 
27b15b7095 2007-11-29       aku:     # var(dv) = dict (item -> list (item)), item  = list (type id)
27b15b7095 2007-11-29       aku:     typemethod predecessors {dv branches} {
712010580a 2007-12-02       aku: 	upvar 1 $dv dependencies
b1666f8ff4 2007-11-29       aku: 	# The predecessors of a branch are all the revisions the
b1666f8ff4 2007-11-29       aku: 	# branches are spawned from, as well as all the branches or
b1666f8ff4 2007-11-29       aku: 	# tags which are their prefered parents.
b1666f8ff4 2007-11-29       aku: 
c784751485 2007-12-02       aku: 	set theset ('[join $branches {','}]')
b1666f8ff4 2007-11-29       aku: 	foreach {bid parent} [state run "
b1666f8ff4 2007-11-29       aku: 	    SELECT B.Bid, R.rid
fbfb531868 2007-12-02       aku: 	    FROM   branch B, revision R
b1666f8ff4 2007-11-29       aku: 	    WHERE  B.bid IN $theset
b1666f8ff4 2007-11-29       aku: 	    AND    B.root = R.rid
b1666f8ff4 2007-11-29       aku: 	"] {
b1666f8ff4 2007-11-29       aku: 	    lappend dependencies([list sym::branch $bid]) [list rev $parent]
b1666f8ff4 2007-11-29       aku: 	}
b1666f8ff4 2007-11-29       aku: 	foreach {bid parent} [state run "
b1666f8ff4 2007-11-29       aku: 	    SELECT B.bid, BX.bid
fbfb531868 2007-12-02       aku: 	    FROM   branch B, preferedparent P, branch BX
b1666f8ff4 2007-11-29       aku: 	    WHERE  B.bid IN $theset
b1666f8ff4 2007-11-29       aku: 	    AND    B.sid = P.sid
b1666f8ff4 2007-11-29       aku: 	    AND    P.pid = BX.sid
b1666f8ff4 2007-11-29       aku: 	"] {
b1666f8ff4 2007-11-29       aku: 	    lappend dependencies([list sym::branch $bid]) [list sym::branch $parent]
b1666f8ff4 2007-11-29       aku: 	}
b1666f8ff4 2007-11-29       aku: 	foreach {bid parent} [state run "
b1666f8ff4 2007-11-29       aku: 	    SELECT B.bid, T.tid
fbfb531868 2007-12-02       aku: 	    FROM   branch B, preferedparent P, tag T
fbfb531868 2007-12-02       aku: 	    WHERE  B.bid IN $theset
b1666f8ff4 2007-11-29       aku: 	    AND    B.sid = P.sid
b1666f8ff4 2007-11-29       aku: 	    AND    P.pid = T.sid
b1666f8ff4 2007-11-29       aku: 	"] {
b1666f8ff4 2007-11-29       aku: 	    lappend dependencies([list sym::branch $bid]) [list sym::tag $parent]
b1666f8ff4 2007-11-29       aku: 	}
9c57055025 2007-12-02       aku: 	return
9c57055025 2007-12-02       aku:     }
9c57055025 2007-12-02       aku: 
9c57055025 2007-12-02       aku:     # result = list (changeset-id)
9c57055025 2007-12-02       aku:     typemethod cs_successors {branches} {
9c57055025 2007-12-02       aku:         # This is a variant of 'successors' which maps the low-level
9c57055025 2007-12-02       aku:         # data directly to the associated changesets. I.e. instead
9c57055025 2007-12-02       aku:         # millions of dependency pairs (in extreme cases (Example: Tcl
9c57055025 2007-12-02       aku:         # CVS)) we return a very short and much more manageable list
9c57055025 2007-12-02       aku:         # of changesets.
9c57055025 2007-12-02       aku: 
9c57055025 2007-12-02       aku: 	set theset ('[join $branches {','}]')
9c57055025 2007-12-02       aku:         return [state run "
9c57055025 2007-12-02       aku: 	    SELECT C.cid
9c57055025 2007-12-02       aku: 	    FROM   branch B, revision R, csitem CI, changeset C
9c57055025 2007-12-02       aku: 	    WHERE  B.bid IN $theset
9c57055025 2007-12-02       aku: 	    AND    B.first = R.rid
9c57055025 2007-12-02       aku:             AND    CI.iid = R.rid
9c57055025 2007-12-02       aku:             AND    C.cid = CI.cid
9c57055025 2007-12-02       aku:             AND    C.type = 0
9c57055025 2007-12-02       aku:     UNION
9c57055025 2007-12-02       aku: 	    SELECT C.cid
9c57055025 2007-12-02       aku: 	    FROM   branch B, preferedparent P, branch BX, csitem CI, changeset C
9c57055025 2007-12-02       aku: 	    WHERE  B.bid IN $theset
9c57055025 2007-12-02       aku: 	    AND    B.sid = P.pid
9c57055025 2007-12-02       aku: 	    AND    BX.sid = P.sid
9c57055025 2007-12-02       aku:             AND    CI.iid = BX.bid
9c57055025 2007-12-02       aku:             AND    C.cid = CI.cid
9c57055025 2007-12-02       aku:             AND    C.type = 2
9c57055025 2007-12-02       aku:     UNION
9c57055025 2007-12-02       aku: 	    SELECT C.cid
9c57055025 2007-12-02       aku: 	    FROM   branch B, preferedparent P, tag T, csitem CI, changeset C
9c57055025 2007-12-02       aku: 	    WHERE  B.bid IN $theset
9c57055025 2007-12-02       aku: 	    AND    B.sid = P.pid
9c57055025 2007-12-02       aku: 	    AND    T.sid = P.sid
9c57055025 2007-12-02       aku:             AND    CI.iid = T.tid
9c57055025 2007-12-02       aku:             AND    C.cid = CI.cid
9c57055025 2007-12-02       aku:             AND    C.type = 1
9c57055025 2007-12-02       aku: 	"]
b1666f8ff4 2007-11-29       aku: 	return
27b15b7095 2007-11-29       aku:     }
84de38d73f 2007-10-10       aku: 
84de38d73f 2007-10-10       aku:     # # ## ### ##### ######## #############
27b15b7095 2007-11-29       aku:     ## Configuration
27b15b7095 2007-11-29       aku: 
27b15b7095 2007-11-29       aku:     pragma -hasinstances   no ; # singleton
27b15b7095 2007-11-29       aku:     pragma -hastypeinfo    no ; # no introspection
27b15b7095 2007-11-29       aku:     pragma -hastypedestroy no ; # immortal
84de38d73f 2007-10-10       aku: }
27b15b7095 2007-11-29       aku: 
27b15b7095 2007-11-29       aku: # # ## ### ##### ######## ############# #####################
27b15b7095 2007-11-29       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
47d52d1efd 2007-11-28       aku: 	namespace import ::vc::fossil::import::cvs::integrity
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
27b15b7095 2007-11-29       aku: 
27b15b7095 2007-11-29       aku: 	# Set up the helper singletons
27b15b7095 2007-11-29       aku: 	namespace eval rev {
27b15b7095 2007-11-29       aku: 	    namespace import ::vc::fossil::import::cvs::state
27b15b7095 2007-11-29       aku: 	    namespace import ::vc::fossil::import::cvs::integrity
27b15b7095 2007-11-29       aku: 	}
27b15b7095 2007-11-29       aku: 	namespace eval sym::tag {
27b15b7095 2007-11-29       aku: 	    namespace import ::vc::fossil::import::cvs::state
27b15b7095 2007-11-29       aku: 	    namespace import ::vc::fossil::import::cvs::integrity
27b15b7095 2007-11-29       aku: 	}
27b15b7095 2007-11-29       aku: 	namespace eval sym::branch {
27b15b7095 2007-11-29       aku: 	    namespace import ::vc::fossil::import::cvs::state
27b15b7095 2007-11-29       aku: 	    namespace import ::vc::fossil::import::cvs::integrity
27b15b7095 2007-11-29       aku: 	}
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