Diff
Not logged in

Differences From:

File tools/cvs2fossil/lib/c2f_prev.tcl part of check-in [27b15b7095] - This commit starts a series of incremental changes not quite completely overhauling the handling of changesets, i.e. of project-level revisions. Actually this series of changes already started with 8ce7ffff21 as the bug it fixes was found when the first parts of the overhaul tripped the new integrity conditions for the modified changesets.

Background: In the last few days I repeatedly ran against the wall of an assertion in pass 9, last of the cycle breakers, with the revision changesets coming in out of order when the symbols were added to the dependency graph.

While walking to the office, and later re-reading the relevant parts of cvs2svn again I had several insights. Trigger was the realization that giving the tag changesets successor dependencies was wrong. Tags describe a state, they have no successors. This caused the re-read, and I recognized that my handling of the symbol changesets was completely wrong, that with using revisions as their data. It should have been the tags and branches. From there their actual dependencies (versus my reuse of revision dependencies) fell out naturally.

I have decided to commit my rewrite of the internals incrementally to make it easier to follow them, despite leaving the sourcebase in an unusable state during the series. One big commit would be much more difficult to understand.

The central change is to the changeset class, which becomes a trinity, holding either revisions, tags, or branches, with type-dependent code to retrieve their dependencies. The remainder of the changes are 'just' adaptions of the users to the changed API.

First change: Add outline of the helper classes, singletons actually, to hold the type-dependent functionality.

by aku on 2007-11-29 05:58:53. [view]

To:

File tools/cvs2fossil/lib/c2f_prev.tcl part of check-in [c74fe3de3f] - Integrate the new singletons with the main class, route the relevant places to them. by aku on 2007-11-29 06:10:18. [view]

@@ -38,10 +38,13 @@
 	} else {
 	    set myid [incr mycounter]
 	}
 
+	integrity assert {[info exists mycstype($cstype)]} {Bad changeset type '$cstype'.}
+
 	set myproject   $project
 	set mytype      $cstype
+	set mytypeobj   ::vc::fossil::import::cvs::project::rev::${cstype}
 	set mysrcid	$srcid
 	set myrevisions $revisions
 	set mypos       {} ; # Commit location is not known yet.
 
@@ -73,21 +76,15 @@
     method id        {} { return $myid }
     method revisions {} { return $myrevisions }
     method data      {} { return [list $myproject $mytype $mysrcid] }
 
-    method bysymbol   {} { return [expr {$mytype eq "sym"}] }
-    method byrevision {} { return [expr {$mytype eq "rev"}] }
+    delegate method bysymbol   to mytypeobj
+    delegate method byrevision to mytypeobj
+    delegate method isbranch   to mytypeobj
+    delegate method istag      to mytypeobj
 
     method setpos {p} { set mypos $p ; return }
     method pos    {}  { return $mypos }
-
-    method isbranch {} {
-	error NOT-USED
-	return [expr {($mytype eq "sym") &&
-		      ($mybranchcode == [state one {
-			  SELECT type FROM symbol WHERE sid = $mysrcid
-		      }])}]
-    }
 
     # result = dict (revision -> list (changeset))
     method successormap {} {
 	# NOTE / FUTURE: Possible bottleneck.
@@ -136,17 +133,17 @@
 
     # revision -> list (revision)
     method nextmap {} {
 	if {[llength $mynextmap]} { return $mynextmap }
-	PullSuccessorRevisions tmp $myrevisions
+	$mytypeobj successors tmp $myrevisions
 	set mynextmap [array get tmp]
 	return $mynextmap
     }
 
     # revision -> list (revision)
     method premap {} {
 	if {[llength $mypremap]} { return $mypremap }
-	PullPredecessorRevisions tmp $myrevisions
+	$mytypeobj predecessors tmp $myrevisions
 	set mypremap [array get tmp]
 	return $mypremap
     }
 
@@ -172,9 +169,9 @@
 	# Array of dependencies (parent -> child). This is pulled from
 	# the state, and limited to successors within the changeset.
 
 	array set dependencies {}
-	PullInternalSuccessorRevisions dependencies $myrevisions
+	$mytypeobj internalsuccessors dependencies $myrevisions
 	if {![array size dependencies]} {return 0} ; # Nothing to break.
 
 	log write 5 csets ...[$self str].......................................................
 
@@ -317,16 +314,9 @@
 	}
 	return
     }
 
-    method timerange {} {
-	set theset ('[join $myrevisions {','}]')
-	return [state run "
-	    SELECT MIN(R.date), MAX(R.date)
-	    FROM revision R
-	    WHERE R.rid IN $theset
-	"]
-    }
+    method timerange {} { return [$mytypeobj timerange $myrevisions] }
 
     method drop {} {
 	state transaction {
 	    state run {
@@ -382,10 +372,18 @@
     variable myid        {} ; # Id of the cset for the persistent
 			      # state.
     variable myproject   {} ; # Reference of the project object the
 			      # changeset belongs to.
-    variable mytype      {} ; # rev or sym, where the cset originated
-			      # from.
+    variable mytype      {} ; # What the changeset is based on
+			      # (revisions, tags, or branches).
+			      # Values: See mycstype. Note that we
+			      # have to keep the names of the helper
+			      # singletons in sync with the contents
+			      # of state table 'cstype', and various
+			      # other places using them hardwired.
+    variable mytypeobj   {} ; # Reference to the container for the
+			      # type dependent code. Derived from
+			      # mytype.
     variable mysrcid     {} ; # Id of the metadata or symbol the cset
 			      # is based on.
     variable myrevisions {} ; # List of the file level revisions in
 			      # the cset.
@@ -403,9 +401,13 @@
     # # ## ### ##### ######## #############
     ## Internal methods
 
     typevariable mycounter        0 ; # Id counter for csets. Last id used.
-    typevariable mycstype -array {} ; # Map cstypes to persistent ids.
+    typevariable mycstype -array {} ; # Map cstypes (names) to persistent
+				      # ids. Note that we have to keep
+				      # the names in the table 'cstype'
+				      # in sync with the names of the
+				      # helper singletons.
 
     typemethod getcstypes {} {
 	foreach {tid name} [state run {
 	    SELECT tid, name FROM cstype;
@@ -855,8 +857,14 @@
     typemethod isbranch   {} { return 0 }
 
     # result = list (mintime, maxtime)
     typemethod timerange {items} {
+	set theset ('[join $items {','}]')
+	return [state run "
+	    SELECT MIN(R.date), MAX(R.date)
+	    FROM revision R
+	    WHERE R.rid IN $theset
+	"]
     }
 
     # var(dv) = dict (revision -> list (revision))
     typemethod internalsuccessors {dv revisions} {