File Annotation
Not logged in
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku: namespace eval ::vc::cvs::ws::branch {}
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku: # Trivial storage of all branch data as a rectangular table.  We can
72dac950c3 2007-09-26       aku: # think up a better suited storage system later, when we know what
72dac950c3 2007-09-26       aku: # type of queries are made to this module.
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku: proc ::vc::cvs::ws::branch::def {f dv deflist} {
72dac950c3 2007-09-26       aku:     upvar 1 $dv date
72dac950c3 2007-09-26       aku:     variable bra
72dac950c3 2007-09-26       aku:     foreach {tag rev} $deflist {
72dac950c3 2007-09-26       aku: 	# ignore non-branch tags
72dac950c3 2007-09-26       aku: 	if {[llength [split $rev .]] < 4} continue
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku: 	if 0 {
72dac950c3 2007-09-26       aku: 	    if { ($rev ne "1.1.1.1") && ![string match *.0.2 $rev] } {
72dac950c3 2007-09-26       aku: 		# 1.1.1.1 is the base of vendor branches, usually. *.0.y
72dac950c3 2007-09-26       aku: 		# is the base of regular branches where nothing is on the
72dac950c3 2007-09-26       aku: 		# branch yet, only its root is marked. Everything else is
72dac950c3 2007-09-26       aku: 		# noteworthy for now.
72dac950c3 2007-09-26       aku: 		puts $f/$rev/$tag
72dac950c3 2007-09-26       aku: 	    }
72dac950c3 2007-09-26       aku: 	}
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku: 	set root [revroot $rev]
72dac950c3 2007-09-26       aku: 	lappend bra [list $date($root) $tag $f $rev]
72dac950c3 2007-09-26       aku:     }
72dac950c3 2007-09-26       aku: }
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku: proc ::vc::cvs::ws::branch::revroot {rev} {
72dac950c3 2007-09-26       aku:     return [join [lrange [split $rev .] 0 end-2] .]
72dac950c3 2007-09-26       aku: }
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku:     # ! Files in a branch can appear only after their root revision
72dac950c3 2007-09-26       aku:     #   exists. This can be checked against the time of the cset which
72dac950c3 2007-09-26       aku:     #   is our base. Branches which have no files yet can be eliminated
72dac950c3 2007-09-26       aku:     #   from consideration.
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku:     # ! All files noted by the base cset as added/modified have to be
72dac950c3 2007-09-26       aku:     #   in the branch root. Branches which do not have such a file can
72dac950c3 2007-09-26       aku:     #   be eliminated from consideration.
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku:     # ! The versions of the added/modified files in the base have
72dac950c3 2007-09-26       aku:     #   match the versions in the branch root. In the sense that they
72dac950c3 2007-09-26       aku:     #   have to be equal or sucessors. The later implies identity in the
72dac950c3 2007-09-26       aku:     #   upper parts (only the last 2 parts are relevant), and equal
72dac950c3 2007-09-26       aku:     #   length.
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku:     # This gives us the branch, and, due to the time information a
72dac950c3 2007-09-26       aku:     # signature for the root.
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku:     #? Can search for the root based on this signature fail ?
72dac950c3 2007-09-26       aku:     #  Yes. Because the signature may contain files which were not
72dac950c3 2007-09-26       aku:     #  actually yet in the root, despite being able to. And which were
72dac950c3 2007-09-26       aku:     #  not modified by the base, so the check 2 above still passes.
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku:     # -> Search for the full signature first, then drop the youngest
72dac950c3 2007-09-26       aku:     # files, search again until match. Check the result against the
72dac950c3 2007-09-26       aku:     # base, that all needed files are present.
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku:     # However - Can search for the root based on the cset data (needed
72dac950c3 2007-09-26       aku:     # files). Gives us another set of candidate roots. Intersect!
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku: proc ::vc::cvs::ws::branch::find {csvalue} {
72dac950c3 2007-09-26       aku:     array set cs $csvalue
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku:     #variable bra
72dac950c3 2007-09-26       aku:     #puts ___________________________________________
72dac950c3 2007-09-26       aku:     #puts [join [lsort -index 0 [lsort -index 1 $bra]] \n]
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku:     Signatures     bd [TimeRelevant $cs(date)]
72dac950c3 2007-09-26       aku:     DropIncomplete bd [concat $cs(added) $cs(changed)]
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku:     #puts ___________________________________________
72dac950c3 2007-09-26       aku:     #parray bd
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku:     if {[array size bd] < 1} {
72dac950c3 2007-09-26       aku: 	puts "NO BRANCH"
72dac950c3 2007-09-26       aku: 	# Deal how?
72dac950c3 2007-09-26       aku: 	# - Abort
72dac950c3 2007-09-26       aku: 	# - Ignore this changeset and try the next one
72dac950c3 2007-09-26       aku: 	#   (Which has higher probability of not matching as it might
72dac950c3 2007-09-26       aku: 	#    be the successor in the branch to this cset and not a base).
72dac950c3 2007-09-26       aku: 	puts ""
72dac950c3 2007-09-26       aku: 	parray cs
72dac950c3 2007-09-26       aku: 	exit
72dac950c3 2007-09-26       aku:     } elseif {[array size bd] > 1} {
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku: 	# While we might have found several tag they may all refer to
72dac950c3 2007-09-26       aku: 	# the same set of files. If that is so we consider them
72dac950c3 2007-09-26       aku: 	# identical and take one as representative of all.
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku: 	set su {}
72dac950c3 2007-09-26       aku: 	foreach {t s} [array get bd] {
72dac950c3 2007-09-26       aku: 	    lappend su [DictSort $s]
72dac950c3 2007-09-26       aku: 	}
72dac950c3 2007-09-26       aku: 	if {[llength [lsort -unique $su]] > 1} {
72dac950c3 2007-09-26       aku: 	    puts "AMBIGOUS. The following branches match:"
72dac950c3 2007-09-26       aku: 	    # Deal how? S.a.
72dac950c3 2007-09-26       aku: 	    puts \t[join [array names bd] \n\t]
72dac950c3 2007-09-26       aku: 	    puts ""
72dac950c3 2007-09-26       aku: 	    parray cs
72dac950c3 2007-09-26       aku: 	    exit
72dac950c3 2007-09-26       aku: 	}
72dac950c3 2007-09-26       aku: 	# Fall through ...
72dac950c3 2007-09-26       aku:     }
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku:     set tg [lindex [array names bd] 0]
72dac950c3 2007-09-26       aku:     set rs [RootOf $bd($tg)]
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku:     #puts "BRANCH = $tg"
72dac950c3 2007-09-26       aku:     #puts "ROOTSG = $rs"
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku:     return [list $tg $rs]
72dac950c3 2007-09-26       aku: }
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku: proc ::vc::cvs::ws::branch::has {ts needed} {
72dac950c3 2007-09-26       aku:     #variable bra
72dac950c3 2007-09-26       aku:     #puts ___________________________________________
72dac950c3 2007-09-26       aku:     #puts [join [lsort -index 0 [lsort -index 1 $bra]] \n]
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku:     Signatures     bd [TimeRelevant $ts]
72dac950c3 2007-09-26       aku:     DropIncomplete bd $needed
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku:     #puts ___________________________________________
72dac950c3 2007-09-26       aku:     #parray bd
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku:     if {[array size bd] < 1} {
72dac950c3 2007-09-26       aku: 	puts "NO BRANCH"
72dac950c3 2007-09-26       aku: 	# Deal how?
72dac950c3 2007-09-26       aku: 	# - Abort
72dac950c3 2007-09-26       aku: 	# - Ignore this changeset and try the next one
72dac950c3 2007-09-26       aku: 	#   (Which has higher probability of not matching as it might
72dac950c3 2007-09-26       aku: 	#    be the successor in the branch to this cset and not a base).
72dac950c3 2007-09-26       aku: 	exit
72dac950c3 2007-09-26       aku:     } elseif {[array size bd] > 1} {
72dac950c3 2007-09-26       aku: 	puts "AMBIGOUS. Following branches match:"
72dac950c3 2007-09-26       aku: 	# Deal how? S.a.
72dac950c3 2007-09-26       aku: 	puts \t[join [array names bd] \n\t]
72dac950c3 2007-09-26       aku: 	exit
72dac950c3 2007-09-26       aku:     }
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku:     set tg [lindex [array names bd] 0]
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku:     #puts "BRANCH = $tg"
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku:     return $tg
72dac950c3 2007-09-26       aku: }
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku: proc ::vc::cvs::ws::branch::RootOf {dict} {
72dac950c3 2007-09-26       aku:     set res {}
72dac950c3 2007-09-26       aku:     foreach {f r} $dict {
72dac950c3 2007-09-26       aku: 	lappend res $f [revroot $r]
72dac950c3 2007-09-26       aku:     }
72dac950c3 2007-09-26       aku:     return $res
72dac950c3 2007-09-26       aku: }
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku: proc ::vc::cvs::ws::branch::DictSort {dict} {
72dac950c3 2007-09-26       aku:     array set a $dict
72dac950c3 2007-09-26       aku:     set r {}
72dac950c3 2007-09-26       aku:     foreach k [lsort [array names a]] {
72dac950c3 2007-09-26       aku: 	lappend r $k $a($k)
72dac950c3 2007-09-26       aku:     }
72dac950c3 2007-09-26       aku:     return $r
72dac950c3 2007-09-26       aku: }
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku: proc ::vc::cvs::ws::branch::DropIncomplete {bv needed} {
72dac950c3 2007-09-26       aku:     upvar 1 $bv bdata
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku:     # Check the needed files against the branch signature. If files
72dac950c3 2007-09-26       aku:     # are missing or not of a matching version drop the branch from
72dac950c3 2007-09-26       aku:     # further consideration.
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku:     foreach {tag sig} [array get bdata] {
72dac950c3 2007-09-26       aku: 	array set rev $sig
72dac950c3 2007-09-26       aku: 	foreach {file rv} $needed {
72dac950c3 2007-09-26       aku: 	    if {![info exists rev($file)] || ![successor $rv $rev($file)]} {
72dac950c3 2007-09-26       aku: 		# file in cset is not in the branch or is present, but
72dac950c3 2007-09-26       aku: 		# not proper version (different lengths, not matching
72dac950c3 2007-09-26       aku: 		# in upper 0..end-2 parts, not equal|successor).
72dac950c3 2007-09-26       aku: 		unset bdata($tag)
72dac950c3 2007-09-26       aku: 		break
72dac950c3 2007-09-26       aku: 	    }
72dac950c3 2007-09-26       aku: 	    continue
72dac950c3 2007-09-26       aku: 	}
72dac950c3 2007-09-26       aku: 	unset rev
72dac950c3 2007-09-26       aku:     }
72dac950c3 2007-09-26       aku:     return
72dac950c3 2007-09-26       aku: }
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku: proc ::vc::cvs::ws::branch::successor {ra rb} {
72dac950c3 2007-09-26       aku:     # a successor-of b ?
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku:     set la [split $ra .]
72dac950c3 2007-09-26       aku:     set lb [split $rb .]
72dac950c3 2007-09-26       aku:     if {
72dac950c3 2007-09-26       aku: 	([llength $la]         != [llength $lb])         ||
72dac950c3 2007-09-26       aku: 	([lrange  $la 0 end-2] ne [lrange  $lb 0 end-2]) ||
72dac950c3 2007-09-26       aku: 	([package vcompare $ra $rb] < 0)
72dac950c3 2007-09-26       aku:     } {
72dac950c3 2007-09-26       aku: 	return 0
72dac950c3 2007-09-26       aku:     } else {
72dac950c3 2007-09-26       aku: 	return 1
72dac950c3 2007-09-26       aku:     }
72dac950c3 2007-09-26       aku: }
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku: proc ::vc::cvs::ws::branch::Signatures {bv deflist} {
72dac950c3 2007-09-26       aku:     upvar 1 $bv bdata
72dac950c3 2007-09-26       aku:     # Sort branch data by symbolic name for the upcoming checks, and
72dac950c3 2007-09-26       aku:     # generate file revision signatures.
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku:     array set bdata {}
72dac950c3 2007-09-26       aku:     foreach item $deflist {
72dac950c3 2007-09-26       aku: 	# item = timestamp tag file revision
72dac950c3 2007-09-26       aku: 	foreach {__ tag file rev} $item break
72dac950c3 2007-09-26       aku: 	lappend bdata($tag) $file $rev
72dac950c3 2007-09-26       aku:     }
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku:     #puts ___________________________________________
72dac950c3 2007-09-26       aku:     #parray bdata
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku:     return
72dac950c3 2007-09-26       aku: }
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku: proc ::vc::cvs::ws::branch::TimeRelevant {date} {
72dac950c3 2007-09-26       aku:     variable bra
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku:     # Retrieve the branch data which definitely comes before (in time)
72dac950c3 2007-09-26       aku:     # the candidate cset. Only this set is relevant to further checks
72dac950c3 2007-09-26       aku:     # and filters.
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku:     set res {}
72dac950c3 2007-09-26       aku:     foreach item $bra {
72dac950c3 2007-09-26       aku: 	# item = timestamp tag file revision
72dac950c3 2007-09-26       aku: 	#        0         1   2    3
72dac950c3 2007-09-26       aku: 	if {[package vcompare [lindex $item 0] $date] > 0} continue
72dac950c3 2007-09-26       aku: 	lappend res $item
72dac950c3 2007-09-26       aku:     }
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku:     #puts ___________________________________________
72dac950c3 2007-09-26       aku:     #puts [join [lsort -index 0 [lsort -index 1 $res]] \n]
72dac950c3 2007-09-26       aku:     return $res
72dac950c3 2007-09-26       aku: }
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku: namespace eval ::vc::cvs::ws::branch {
72dac950c3 2007-09-26       aku:     variable bra {}
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku:     namespace export def find successor revroot has
72dac950c3 2007-09-26       aku: }
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku: package provide vc::cvs::ws::branch 1.0
72dac950c3 2007-09-26       aku: return
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku:     # Queries ...
72dac950c3 2007-09-26       aku:     # - Get set of files and revs for branch B which can be in it by the time T
72dac950c3 2007-09-26       aku:     # - Check if a file referenced a/m instruction is in a set of files
72dac950c3 2007-09-26       aku:     #   and revision, identical or proper sucessor.
72dac950c3 2007-09-26       aku:     # => Combination
72dac950c3 2007-09-26       aku:     #    Can branch B match the cset file a/m at time T ?
72dac950c3 2007-09-26       aku:     # => Full combination
72dac950c3 2007-09-26       aku:     #    Give me the list of branches which can match the cset file a/m
72dac950c3 2007-09-26       aku:     #    at time T.
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku:     # Branch DB organization => (Tag -> (Time -> (File -> Rev)))
72dac950c3 2007-09-26       aku:     # The full combination actually does not need a complex structure.
72dac950c3 2007-09-26       aku:     # We can simply scan a plain list of branch data.
72dac950c3 2007-09-26       aku:     # The only alternative is an inverted index.
72dac950c3 2007-09-26       aku:     # Time -> ((File -> Rev) -> Tag). Difficult to process.
72dac950c3 2007-09-26       aku:     # Linear scan:
72dac950c3 2007-09-26       aku:     # - Time after T   => drop
72dac950c3 2007-09-26       aku:     # - File !in a/m   => drop
72dac950c3 2007-09-26       aku:     # - Version !match => drop
72dac950c3 2007-09-26       aku:     # -- Collect tag
72dac950c3 2007-09-26       aku:     # Then lsort -unique for our result.
72dac950c3 2007-09-26       aku:     # NO - The file check is inverted - All files have to be in a/m for the base, not a/m in files
72dac950c3 2007-09-26       aku:     # == - This also breaks the issue for same-branch detection -
72dac950c3 2007-09-26       aku:     #    future csets in the branch do not have that property.
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku:     puts ___________________________________________
72dac950c3 2007-09-26       aku:     # Show only branch data which definitely comes before the
72dac950c3 2007-09-26       aku:     # candidate cset
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku:     array set n [concat $cs(added) $cs(changed)]
72dac950c3 2007-09-26       aku:     set xx {}
72dac950c3 2007-09-26       aku:     set bb {}
72dac950c3 2007-09-26       aku:     ::foreach x $bra {
72dac950c3 2007-09-26       aku: 	::foreach {ts tag f r} $x break
72dac950c3 2007-09-26       aku: 	if {[package vcompare $ts $cs(date)] > 0} continue
72dac950c3 2007-09-26       aku: 	if {![info exists n($f)]} continue
72dac950c3 2007-09-26       aku: 	if {
72dac950c3 2007-09-26       aku: 	    ([llength [split $n($f) .]] != [llength [split $r .]]) ||
72dac950c3 2007-09-26       aku: 	    ([lrange [split $n($f) .] 0 end-2] ne [lrange [split $r .] 0 end-2]) ||
72dac950c3 2007-09-26       aku: 	    ([package vcompare $n($f) $r] < 0)
72dac950c3 2007-09-26       aku: 	} continue
72dac950c3 2007-09-26       aku: 	lappend xx $x
72dac950c3 2007-09-26       aku: 	lappend bb $tag
72dac950c3 2007-09-26       aku:     }
72dac950c3 2007-09-26       aku:     puts [join [lsort -index 0 [lsort -index 1 $xx]] \n]
72dac950c3 2007-09-26       aku:     puts [join [lsort -unique $bb] \n]
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku: exit
72dac950c3 2007-09-26       aku: 
72dac950c3 2007-09-26       aku: